package com.xd.core.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ancun.netsign.client.NetSignClient;
import com.ancun.netsign.model.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
import com.xd.common.config.RabbitConfig;
import com.xd.common.constant.SysConstant;
import com.xd.common.exception.XkdException;
import com.xd.common.properties.AqHtProperties;
import com.xd.common.util.*;
import com.xd.core.api.dto.*;
import com.xd.core.api.service.ApiContractService;
import com.xd.core.api.vo.CertificationSignUrlLinkVo;
import com.xd.core.api.vo.ContractInfoVo;
import com.xd.core.api.vo.NotarizationCarmortgageVo;
import com.xd.core.api.vo.NotarizationContractVo;
import com.xd.core.business.entity.*;
import com.xd.core.business.mapper.*;
import com.xd.core.business.vo.RepaymentInsuranceSchedule;
import com.xd.core.company.entity.Company;
import com.xd.core.company.entity.CompanyContract;
import com.xd.core.company.mapper.CompanyContractMapper;
import com.xd.core.company.mapper.CompanyMapper;
import com.xd.core.company.service.ICompanyService;
import com.xd.core.debt.entity.Debt;
import com.xd.core.debt.mapper.DebtMapper;
import com.xd.core.h5.vo.AddSignerVo;
import com.xd.core.note.IAsyncService;
import com.xd.core.product.entity.Product;
import com.xd.core.product.mapper.ProductMapper;
import com.xd.core.system.entity.Dictionary;
import com.xd.core.system.mapper.CityInfoMapper;
import com.xd.core.system.mapper.DictionaryMapper;
import com.xd.core.system.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.client.ResourceAccessException;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.net.SocketTimeoutException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ApiContractServiceImpl implements ApiContractService {
    @Value("${aes.key}")
    private String aesKey;
    @Value("${aqht.faceredirectUrl}")
    private String faceredirectUrl;
    @Autowired
    private DictionaryMapper dictionaryMapper;
    @Value("${image.contract}")
    private String contractUrl;
    @Value("${gongzheng.sm4key}")
    private String sm4key;
    @Value("${gongzheng.appid}")
    private String appid;
    @Value("${gongzheng.baseurl}")
    private String baseurl;
    @Value("${gongzheng.unifiedOrderUrl}")
    private String unifiedOrderUrl;
    @Value("${gongzheng.cancelOrder}")
    private String cancelOrder;
    @Value("${gongzheng.getSignUrlLink}")
    private String getSignUrlLink;
    @Value("${image.localPathDir}")
    private String localPathDir;
    @Value("${image.localUrlPath}")
    private String localUrlPath;
    @Value("${spring.profiles.active}")
    private String active;
    @Value("${dkcompany.organizationCardNum}")
    private String organizationCardNum;
    @Value("${dkcompany.organizationName}")
    private String organizationName;
    @Value("${dkcompany.organizationAddress}")
    private String organizationAddress;
    @Value("${dkcompany.organizationPhone}")
    private String organizationPhone;
    @Value("${dkcompany.name}")
    private String name;
    @Value("${dkcompany.yyzzurl}")
    private String yyzzurl;
    @Value("${dkcompany.fddbrzmurl}")
    private String fddbrzmurl;
    @Value("${dkcompany.sfzzm}")
    private String sfzzm;
    @Value("${dkcompany.sfzfm}")
    private String sfzfm;


    @Autowired
    private NetSignClient netSignClient;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private DebtMapper debtMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private CompanyContractMapper companyContractMapper;
    @Autowired
    private AqHtProperties aqHtProperties;
    @Autowired
    private IncomingInfoMapper incomingInfoMapper;
    @Autowired
    private IncomingInfoSuppMapper incomingInfoSuppMapper;
    @Autowired
    private CityInfoMapper cityInfoMapper;
    @Autowired
    private CreditMapper creditMapper;
    @Autowired
    private IncomingCommonLoanMapper incomingCommonLoanMapper;
    private static final String signPwd = "xdfw";
    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private FileService fileService;
    @Autowired
    private OutInfoMapper outInfoMapper;
    @Autowired
    private InsuranceCompanyInfoMapper insuranceCompanyInfoMapper;
    @Autowired
    private CarCreditMapper carCreditMapper;
    @Autowired
    private CertificationOrderMapper certificationOrderMapper;
    @Lazy
    @Autowired
    private IAsyncService iAsyncService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Value("${baofush.loans_out_account_offline}")//放款款线下打款账户
    private String loans_out_account_offline;
    @Value("${baofush.loans_in_account_offline}")//回款线下打款账户
    private String loans_in_account_offline;
    @Value("${baofush.tow_loans_in_account_offline}")//渠道二回款线下打款账户
    private String tow_loans_in_account_offline;
    private static final int maxRetry = 10;//最大尝试机制
    private static final int sleepMillis = 1000;//休眠时间
    @Autowired
    private ICompanyService iCompanyService;
    private static final String serialNo = "serialNo";
    @Resource
    ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private CertificationMapper certificationMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    private static final String CONTRACT_LOCK_KEY = "lock_contract";
    @Autowired
    private RedissonClient redissonClient;


    @Override
    public String companyAuthMobile3(Integer companyId) {
        //认证企业三要素实名认证  返回流水号与验证码
        CompanyAuthMobile3Dto companyAuthMobile3Dto = companyMapper.getCompanyAuthInfo(companyId);
        if (companyAuthMobile3Dto.getAuthStatus().equals("1"))
            throw new XkdException("已认证");
        companyAuthMobile3Dto.setMobile(AESUtil.decrypt(companyAuthMobile3Dto.getMobile(), aesKey));
        return authMobile3(companyAuthMobile3Dto);
    }

    @Override
    public void verifyCaptcha(VerifyCaptchaDto verifyCaptchaVo) {
        Integer companyId = verifyCaptchaVo.getCompanyId();
        Company byId = companyMapper.selectById(companyId);//法人电话
        verifyCaptchaVo.setMobile(AESUtil.decrypt(byId.getCompanyPhone(), aesKey));
//        verifyCaptchaVo.setMobile(AESUtil.decrypt(verifyCaptchaVo.getMobile(), aesKey));
        verifyCaptchaVo.setCreditCode(byId.getUnifiedSocialCreditCode());
        //认证验证码 流水号
        String verify = verify(verifyCaptchaVo);
        //添加企业用户
        verifyCaptchaVo.setSerialNo(verify);
        String s = addEnterpriseUser(verifyCaptchaVo);
        //存入企业信息包括签章信息 并修改认证企业状态
        Company company = new Company();
        company.setId(verifyCaptchaVo.getCompanyId());
        company.setAuthStatus(SysConstant.ZH_CHECK_PASS_STATUS);
        company.setSealNo(s);
        companyMapper.updateById(company);

    }

    //验证是否再次签署合同
    public Contract checkContractInfo(Integer outId, String contractType) {
        //查询是否签署过合同
        Contract oldContract = null;
        if (contractType.equals(SysConstant.CONTRACT_TYPE_ONE)) {
            oldContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getIncomingId, outId).eq(Contract::getType, contractType));
        } else {
            oldContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getOutId, outId).eq(Contract::getType, contractType));
        }
        //判断是否是再次签署
        if (oldContract != null) {
            if (oldContract.getStatus().equals(SysConstant.CONTRACT_TODO)) {
                throw new XkdException("合同待签署中，请勿重复发起");
            } else if (oldContract.getStatus().equals(SysConstant.CONTRACT_DO)) {
                throw new XkdException("合同已签署，请勿重复发起");
            }
        }
        return oldContract;
    }

    //验证公司是否再次签署合同
    public CompanyContract checkCompanyContractInfo(Integer companyId, String contractType) {
        //查询是否签署过合同
        CompanyContract oldContract = companyContractMapper.selectOne(new LambdaQueryWrapper<CompanyContract>().eq(CompanyContract::getCompanyId, companyId).eq(CompanyContract::getType, contractType));
        //判断是否是再次签署
        if (oldContract != null) {
            if (oldContract.getStatus().equals(SysConstant.CONTRACT_TODO)) {
                throw new XkdException("合同待签署中，请勿重复发起");
            } else if (oldContract.getStatus().equals(SysConstant.CONTRACT_DO)) {
                throw new XkdException("合同已签署，请勿重复发起");
            }
        }
        return oldContract;
    }

    //插入或更新合同信息
    @Transactional
    public void saveContractInfo(Date contractCreate, Contract oldContract, ContractOutput data, String contractNo, IncomingInfo incomingInfo, String contractType, Integer outId) {
        if (oldContract != null) {//代表不是第一次签约
            contractMapper.deleteById(oldContract.getContractId());
            //如果是重新签约贷款合同，删除其他2个合同
            //担保合同，抵押合同
//            if (oldContract.getType().equals(SysConstant.CONTRACT_TYPE_TOW)) {
//                contractMapper.deleteByDKContract(incomingInfo.getIncomingId());
//            }
        }
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(contractType);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(outId);
        if (!contractType.equals(SysConstant.CONTRACT_TYPE_ELEVEN) && !contractType.equals(SysConstant.CONTRACT_TYPE_TEN))
            c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);
    }

    //插入或更新公司合同信息
    @Transactional
    public void saveCompanyContractInfo(Date contractCreate, CompanyContract oldContract, ContractOutput data, String contractNo, Integer companyId, String contractType) {
        log.info("结果{}", JSONObject.toJSONString(data));
        if (oldContract != null) {//代表不是第一次签约
            companyContractMapper.deleteById(oldContract.getContractId());
        }
        //保存签约合同信息
        CompanyContract companyContract = new CompanyContract();
        companyContract.setCompanyId(companyId);
        companyContract.setStatus(SysConstant.CONTRACT_TODO);
        companyContract.setCreateTime(contractCreate);
        companyContract.setName(data.getContractName());
        companyContract.setContractOrder(contractNo);
        companyContract.setType(contractType);
        companyContract.setPreviewUrl(data.getPreviewUrl());
//        companyContract.setSignUrl(data.getSignUser().get(0).getSignUrl()); //无感验签没有
        companyContractMapper.insert(companyContract);


    }

    @Override
    public void authorizationToUse(Integer id) {
        Date contractCreate = new Date();
        Contract oldContract = checkContractInfo(id, SysConstant.CONTRACT_TYPE_ONE);
        //查询进件信息
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(id);
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        String idCard = incomingInfo.getIdCard();
        //添加陌生用户
        addStrangerV2(idCard);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("个人信息授权书");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getGrxxsqstemplateNo());
        Map<String, String> map = new HashMap<>();
        DateTime date = DateUtil.date();
        map.put("Name", incomingInfo.getName());
        map.put("CardId", incomingInfo.getIdCard());
        map.put("Y", String.valueOf(DateUtil.year(date)));
        map.put("M", String.valueOf(DateUtil.month(date) + 1));
        map.put("D", String.valueOf(DateUtil.dayOfMonth(date)));
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        //创建合同
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        //发起签署合同
        List<ContractUserInput> userInputList = new ArrayList<>();
        /*
         * 用户
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(idCard);
        c2.setSignType(3);
        c2.setNoticeMobile(userPhone);
        c2.setIsNotice(1);
        c2.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        userInputList.add(c2);

        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署人发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        saveContractInfo(contractCreate, oldContract, data, contractNo, incomingInfo, SysConstant.CONTRACT_TYPE_ONE, null);
    }

    @Override
    public void contractNotifyUrl(QMHD qmhd) throws InterruptedException {
        log.info("合同签署回调执行：" + qmhd.getContractNo());
        LambdaQueryWrapper<Contract> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Contract::getContractNo, qmhd.getContractNo());
        Contract contract = null;
        for (int i = 1; i <= maxRetry; i++) {
            contract = contractMapper.selectOne(lqw);
            log.info("第 {} 次查询合同数据：{}", i, contract);
            if (contract != null)
                break;
            try {
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                log.warn("等待过程中被中断", e);
                Thread.currentThread().interrupt(); // 恢复中断状态
                break;
            }
        }
        if (contract == null) {
            log.error("重试 {} 次后仍未获取到合同数据", maxRetry);
            throw new RuntimeException("未获取到合同数据，请稍后再试");
        }
        String baseUrl = localPathDir + contractUrl + "/" + contract.getCompanyId() + "/";
        String filePath = qmhd.getContractNo() + ".pdf";
        String fileUrl = baseUrl + filePath;//文件下载路径
        File dirFile = new File(baseUrl);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        ApiRespBody<DownloadContractOutput> body = netSignClient.downloadContract(qmhd.getContractNo(), 1, fileUrl);
        int code = body.getCode();
        if (code != 100000) {
            log.info("下载失败");
            throw new XkdException(body.getMsg());
        }
        String type = contract.getType();
        LambdaQueryWrapper<Contract> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(Contract::getContractNo, qmhd.getContractNo());
        Contract c = new Contract();
        c.setContract(contractUrl + "/" + contract.getCompanyId() + "/" + filePath);
        c.setContractTime(DateUtil.parse(qmhd.getSignTime()));
        c.setStatus("2");
        contractMapper.update(c, lqw2);
        OutInfo outInfo = outInfoMapper.selectById(contract.getOutId());
        if (type.equals(SysConstant.CONTRACT_TYPE_ELEVEN)) {//债权转让确认单
            debtMapper.updateConversionStatus(contract.getOutId());
        } else if (type.equals(SysConstant.CONTRACT_TYPE_ONE)) {//个人信息授权书
            incomingInfoMapper.updatePersonalInfoStatus(contract.getIncomingId());
        } else if (type.equals(SysConstant.CONTRACT_TYPE_TOW)) {//借款合同 代表签约完成
            String status = SysConstant.BUSINESS_STATUS_SEVEN;
            IncomingInfo incomingInfo = incomingInfoMapper.selectById(contract.getIncomingId());
            LambdaQueryWrapper<Product> eq = new LambdaQueryWrapper<Product>().eq(Product::getProductId, incomingInfo.getProductId());
            Product product = productMapper.selectOne(eq);
            //判断是否需要抵押和公证
            if ((SysConstant.PRODUCT_ONE.equals(product.getType()) ||
                    (SysConstant.PRODUCT_FOUR.equals(product.getType()) && incomingInfo.getIsJydMortgage().equals("0")))
                    && !SysConstant.CONTROVERSY_ONE.equals(outInfo.getControversy())) {
                status = SysConstant.BUSINESS_STATUS_ELEVEN;
            }
            outInfoMapper.updateStatus(status, contract.getOutId());
        } else if (type.equals(SysConstant.CONTRACT_TYPE_TWELVE)) {//车险分期
            //查询预付款回调是否执行
            IncomingInfo incomingInfo = incomingInfoMapper.selectById(contract.getIncomingId());
            if (!incomingInfo.getStatus().equals(SysConstant.BUSINESS_STATUS_ELEVEN)) {
                incomingInfoMapper.updateStatus(SysConstant.BUSINESS_STATUS_SEVEN, contract.getIncomingId());
            }
        }
        //扣除单笔服务费用,结清证明不扣
        if (!type.equals(SysConstant.CONTRACT_TYPE_TEN)) {
            iCompanyService.deductingBalanceMain(null, null, contract.getIncomingId(), null, SysConstant.BUSINESS_FEE_FOUR, null, null, null);
        }
    }

    @Override
    public void contractCallbackUrl(QMHD qmhd) {
        //合同签署失败
        String status = qmhd.getStatus();
        String contractNo = qmhd.getContractNo();

        LambdaQueryWrapper<Contract> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(Contract::getContractNo, qmhd.getContractNo());
        Contract oldContract = null;
        for (int i = 1; i <= maxRetry; i++) {
            oldContract = contractMapper.selectOne(lqw2);
            log.info("第 {} 次查询合同数据：{}", i, oldContract);
            if (oldContract != null)
                break;
            try {
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                log.warn("等待过程中被中断", e);
                Thread.currentThread().interrupt(); // 恢复中断状态
                break;
            }
        }
        if (oldContract == null) {
            log.error("重试 {} 次后仍未获取到合同数据", maxRetry);
            throw new RuntimeException("未获取到合同数据，请稍后再试");
        }


        Contract contract = new Contract();
        contract.setContractNo(contractNo);
        contract.setStatus(status);
        if (status.equals("-3"))//失败
            contract.setStatus(SysConstant.CONTRACT_FAIL);
        LambdaQueryWrapper<Contract> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Contract::getContractNo, contractNo);
        contractMapper.update(contract, lqw);
    }

    @Override
    public void companyContractCallback(QMHD qmhd) {
        //合同签署失败
        String status = qmhd.getStatus();
        String contractNo = qmhd.getContractNo();

        LambdaQueryWrapper<CompanyContract> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(CompanyContract::getContractOrder, qmhd.getContractNo());
        CompanyContract oldContract = null;
        for (int i = 1; i <= maxRetry; i++) {
            oldContract = companyContractMapper.selectOne(lqw2);
            log.info("第 {} 次查询合同数据：{}", i, oldContract);
            if (oldContract != null)
                break;
            try {
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                log.warn("等待过程中被中断", e);
                Thread.currentThread().interrupt(); // 恢复中断状态
                break;
            }
        }
        if (oldContract == null) {
            log.error("重试 {} 次后仍未获取到合同数据", maxRetry);
            throw new RuntimeException("未获取到合同数据，请稍后再试");
        }

        CompanyContract contract = new CompanyContract();
        contract.setContractOrder(contractNo);
        if (status.equals("-3")) {//失败
            status = SysConstant.CONTRACT_FAIL;
        }
        contract.setStatus(status);
        LambdaQueryWrapper<CompanyContract> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CompanyContract::getContractOrder, contractNo);
        companyContractMapper.update(contract, lqw);
        if (contract.getType().equals(SysConstant.COMPANY_CONTRACT_TYPE_ONE))
            //修改公司表签署状态
            companyMapper.updateContractStatus(contract.getCompanyId(), status);
    }

    @Override
    public void resend(String serialNo) {
        ApiRespBody<Void> body = netSignClient.resendAuthCaptcha(serialNo);
        int code = body.getCode();
        if (code != 100000) {
            throw new XkdException(body.getMsg());
        }
    }

    @Override
    public String getContract(String contractNo) {
        ApiRespBody body = netSignClient.getContractInfo(contractNo);
        int code = body.getCode();
        if (code != 100000) {
            throw new XkdException(body.getMsg());
        }
        Object data = body.getData();
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(data));
        return jsonObject.getString("previewUrl");
    }

    private String downloadContract(String contractNo, Integer companyId) {
        //下载贷款合同
        String baseUrl = localPathDir + contractUrl + "/" + companyId + "/";
        String filePath = contractNo + ".pdf";
        String fileUrl = baseUrl + filePath;//文件下载路径
        File dirFile = new File(baseUrl);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        ApiRespBody<DownloadContractOutput> body = netSignClient.forceDownloadContract(contractNo, null, 1, fileUrl);
        int code = body.getCode();
        if (code != 100000) {
            log.info("下载失败");
            throw new XkdException(body.getMsg());
        }
        return contractUrl + "/" + companyId + "/" + filePath;
    }

    @Override
    public void notarizationContract(SignContractDto signContractDto) {
        log.info("开始创建公证合同");
        Integer incomingId = signContractDto.getIncomingId();
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        String status = incomingInfo.getStatus();
        Integer outId = signContractDto.getOutId();
        if (signContractDto.getSignType().equals("0")) {
            if (!status.equals(SysConstant.BUSINESS_STATUS_FIVE))
                throw new XkdException("请勿重复签约");
        } else if (signContractDto.getSignType().equals("1")) {//再次签约
            OutInfo outInfo = outInfoMapper.selectOne(new LambdaQueryWrapper<OutInfo>().eq(OutInfo::getOutId, outId));
            if (!outInfo.getStatus().equals(SysConstant.BUSINESS_STATUS_SIX))
                throw new XkdException("请勿重复签约");
            Certification certification = certificationMapper.selectById(signContractDto.getCertificationId());
            if (!certification.getStatus().equals(SysConstant.CERTIFICATION_STATUS_ONE))
                throw new XkdException("公证流程尚未完成");
            //修改公证状态为公证中
            certificationMapper.updateStatus(signContractDto.getCertificationId());

            signContractDto.setRate(outInfo.getRate());
            signContractDto.setTerm(outInfo.getTerm());
            signContractDto.setLoanMethod(outInfo.getLoanMethod());
            signContractDto.setLoanAmount(outInfo.getOutLoan());
            signContractDto.setRepayFrequency(outInfo.getRepayFrequency());
            signContractDto.setUsed(outInfo.getUsed());
            signContractDto.setControversy(outInfo.getControversy());
            signContractDto.setCityRemark(outInfo.getCityRemark());
        }
        //贷款合同 - 抵押合同 - 担保合同
        HashMap<String, Object> map = notarizationBorrowing(signContractDto);
        ArrayList<NotarizationContractVo> notarizationContractVos = (ArrayList<NotarizationContractVo>) map.get("notarizationContractVos");//创建合同信息
        List<Proposer> proposers = (List<Proposer>) map.get("proposers");//关系人
        List<LoadInfo> loadInfo = (List<LoadInfo>) map.get("loadInfo");//贷款信息
        List<MortgageInfo> carMortgageInfo = (List<MortgageInfo>) map.get("carMortgageInfo");//车辆抵押信息
        String DKContractNo = (String) map.get("DKContractNo");
        //还款承诺函
        NotarizationContractVo n1 = notarizationRepaymentCommitmentLetter(signContractDto, DKContractNo);
        //委托代扣协议
        NotarizationContractVo n2 = notarizationWithhold(signContractDto, DKContractNo);
        ArrayList<ContractsInfo> contractsInfos = new ArrayList<>();
        notarizationContractVos.forEach(n -> {
            ContractsInfo contractsInfo = new ContractsInfo();
            contractsInfo.setFileName(n.getContractName());
            contractsInfo.setFileCode(n.getFileCode());
            contractsInfo.setFileUrl(n.getContractUrl());
            contractsInfo.setContractNum(n.getContractNo());
            contractsInfos.add(contractsInfo);
        });
        contractsInfos.add(new ContractsInfo(n1.getContractUrl(), n1.getContractName(), n1.getFileCode(), n1.getContractNo()));
        contractsInfos.add(new ContractsInfo(n2.getContractUrl(), n2.getContractName(), n2.getFileCode(), n2.getContractNo()));


        //公证API
        UnifiedOrderDto unifiedOrderDto = new UnifiedOrderDto();
        unifiedOrderDto.setOrgId(1);
        unifiedOrderDto.setProdCode("bkxd");
        unifiedOrderDto.setPlatformName("宝坤网络小贷");
        String notaryCode = "";
        String productType = productMapper.getProductType(incomingId);
        switch (productType) {
            case SysConstant.PRODUCT_ONE:
                notaryCode = "5033";
                break;
            case SysConstant.PRODUCT_TWO:
                notaryCode = "5030";
                break;
            case SysConstant.PRODUCT_THREE:
                notaryCode = "5031";
                break;
            case SysConstant.PRODUCT_FOUR:
                if (incomingInfo.getIsJydMortgage().equals("1")) {
                    notaryCode = "5032";
                } else {
                    notaryCode = "5033";
                }
                break;
        }
        unifiedOrderDto.setNotaryCode(notaryCode);
        unifiedOrderDto.setTotalNotaryNum(1);
        String certificationCode = OrderNumUtil.getCertificationCode();
        unifiedOrderDto.setThirdPartyOrderId(certificationCode);
        unifiedOrderDto.setProposerList(proposers);
        unifiedOrderDto.setContractsInfos(contractsInfos);
        unifiedOrderDto.setLoadInfo(loadInfo);
        if (CollectionUtils.isNotEmpty(carMortgageInfo)) {
            unifiedOrderDto.setMortgageInfo(carMortgageInfo);
        }
        log.info("公证请求参数：{}", unifiedOrderDto);
        String s = Sm4Util.encryptEcb(sm4key, JSONObject.toJSONString(unifiedOrderDto));
        HashMap<String, Object> json = new HashMap<>();
        json.put("appId", appid);
        json.put("data", s);
        ResponseEntity<JSONObject> objectResponseEntity = restTemplateUtil.postJson(baseurl + unifiedOrderUrl, json, JSONObject.class);
        JSONObject body = objectResponseEntity.getBody();
        log.info("公证结果：{}", objectResponseEntity);
        if (body.getString("code").equals("200")) {
            String data = body.getString("data");
            String s1 = Sm4Util.decryptEcb(sm4key, data);
            JSONObject decryptEcb = com.alibaba.fastjson.JSONObject.parseObject(s1);
            String orderNum = decryptEcb.getString("orderNum");
            Date createTime = decryptEcb.getDate("createTime");
            CertificationOrder certificationOrder = new CertificationOrder();
            certificationOrder.setOrderNo(certificationCode);
            certificationOrder.setOrderNum(orderNum);
            certificationOrder.setCertificationId(signContractDto.getCertificationId());
            certificationOrder.setCreateTime(createTime);
            certificationOrder.setOutId(outId);
            certificationOrder.setJsonData(JSONObject.toJSONString(unifiedOrderDto));
            certificationOrder.setCreditId(signContractDto.getCreditId());
            certificationOrder.setIncomingId(signContractDto.getIncomingId());
            certificationOrder.setCompanyId(incomingInfo.getCompanyId());
            certificationOrderMapper.insert(certificationOrder);
        } else {
            // 发送消息到MQ
            log.error("申请公证失败：{}", body.getString("msg"));
            sendCertificationFailMessage(signContractDto);
            throw new XkdException(body.getString("msg"));
        }

    }

    //公证失败回滚数据
    private void sendCertificationFailMessage(SignContractDto msg) {
        log.info("发送公证失败消息");
        rabbitTemplate.convertAndSend(
                RabbitConfig.CERTIFICATION_EXCHANGE,
                RabbitConfig.CERTIFICATION_ROUTING_KEY,
                msg);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void notarizationRevocation(String orderNo) {
        CertificationOrder certificationOrder = certificationOrderMapper.selectById(orderNo);
        if (certificationOrder == null)
            throw new XkdException("该订单不存在");
        if (!certificationOrder.getStatus().equals("0"))//公证中
            throw new XkdException("公证流程已完成");
        HashMap<String, String> cancelOrderMap = new HashMap<>();
        cancelOrderMap.put("orderNum", certificationOrder.getOrderNum());
        log.info("公证请求参数：{}", cancelOrderMap);
        String s = Sm4Util.encryptEcb(sm4key, JSONObject.toJSONString(cancelOrderMap));
        HashMap<String, Object> json = new HashMap<>();
        json.put("appId", appid);
        json.put("data", s);
        ResponseEntity<JSONObject> objectResponseEntity = restTemplateUtil.postJson(baseurl + cancelOrder, json, JSONObject.class);
        JSONObject body = objectResponseEntity.getBody();
        log.info("公证结果：{}", objectResponseEntity);
        if (body.getString("code").equals("200")) {
            //删除创建的合同(为了重新申请公证)
            List<String> removeContracts = contractMapper.selectRemoveContracts(certificationOrder.getOutId());
            LambdaQueryWrapper<Contract> lqw = new LambdaQueryWrapper<>();
            ArrayList<String> list = new ArrayList<>();
            list.add(SysConstant.CONTRACT_TYPE_TOW);
            list.add(SysConstant.CONTRACT_TYPE_THREE);
            list.add(SysConstant.CONTRACT_TYPE_FIVE);
            list.add(SysConstant.CONTRACT_TYPE_SIX);
            list.add(SysConstant.CONTRACT_TYPE_SEVEN);
            lqw.eq(Contract::getOutId, certificationOrder.getOutId()).in(Contract::getType, list);
            contractMapper.delete(lqw);
            fileService.filesRemove(removeContracts);
            //删除公证
            certificationMapper.deleteById(certificationOrder.getCertificationId());
            //删除放款信息
            OutInfo outInfo = outInfoMapper.selectById(certificationOrder.getOutId());
            outInfoMapper.deleteById(certificationOrder.getOutId());
            //删除公证订单
            certificationOrderMapper.delete(new LambdaQueryWrapper<CertificationOrder>().eq(CertificationOrder::getOutId, certificationOrder.getOutId()));
            //修改授信金额
            creditMapper.updateCreditAmountRest(outInfo.getOutLoan().multiply(new BigDecimal(-1)), certificationOrder.getCreditId());
            log.info("撤销公证成功");
        } else {
            throw new XkdException("撤销公证失败");
        }
    }

    @Override
    public List<CertificationSignUrlLinkVo> getSignUrlLink(String orderNo) {
        if (StringUtils.isNotBlank(orderNo)) {
            CertificationOrder certificationOrder = certificationOrderMapper.selectById(orderNo);
            HashMap<String, String> map = new HashMap<>();
            map.put("orderNum", certificationOrder.getOrderNum());
            log.info("获取公证签署链接请求参数：{}", map);
            String s = Sm4Util.encryptEcb(sm4key, JSONObject.toJSONString(map));
            HashMap<String, Object> json = new HashMap<>();
            json.put("appId", appid);
            json.put("data", s);
            ResponseEntity<JSONObject> objectResponseEntity = null;
            try {
                objectResponseEntity = restTemplateUtil.postJson(baseurl + getSignUrlLink, json, JSONObject.class);
            } catch (ResourceAccessException e) {
                if (e.getCause() instanceof SocketTimeoutException) {
                    // 处理连接/读取超时
                    log.error("请求超时: {}", e.getCause().getMessage());
                    throw new XkdException("获取链接失败，请求超时，请稍后再试");
                } else {
                    // 其他资源访问异常
                    log.error("请求失败: {}", e.getMessage(), e);
                }
            }
            JSONObject body = objectResponseEntity.getBody();
            log.info("获取公证签署链接结果：{}", objectResponseEntity);
            if (body.getString("code").equals("200")) {
                String data = body.getString("data");
                String s1 = Sm4Util.decryptEcb(sm4key, data);
                //返回链接
                List<CertificationSignUrlLinkVo> certificationSignUrlLinkVos = JSONObject.parseArray(s1, CertificationSignUrlLinkVo.class);
                String jsonData = certificationOrder.getJsonData();
                UnifiedOrderDto unifiedOrderDto = JSONObject.parseObject(jsonData, UnifiedOrderDto.class);
                List<Proposer> proposerList = unifiedOrderDto.getProposerList();
                for (CertificationSignUrlLinkVo c : certificationSignUrlLinkVos) {
                    for (Proposer p : proposerList) {
                        if (p.getProposerId().equals(c.getProposerId())) {
                            c.setName(p.getName());
                        }
                    }
                }
                return certificationSignUrlLinkVos;
            } else {
                log.error("获取公证签署链接失败：{}", body.getString("msg"));
                throw new XkdException(body.getString("msg"));
            }
        }
        return Collections.emptyList();
    }

    @Override
    public List<ContractInfoVo> getContractStatus(String contractNo) {
        ApiRespBody contractInfo = netSignClient.getContractInfo(contractNo);
        if (contractInfo.getCode() == 100056)
            throw new XkdException("参数错误，合同编号为空");
        if (contractInfo.getCode() == 100066)
            throw new XkdException("合同不存在");
        if (contractInfo.getCode() == 100205)
            throw new XkdException("短链接生成失败");
        if (contractInfo.getCode() == 100613)
            throw new XkdException("合同已删除");
        Object data = contractInfo.getData();
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(data), JSONObject.class);
        String signUser = jsonObject.getString("signUser");
        List<ContractInfoVo> contractInfoVos = JSONObject.parseArray(signUser, ContractInfoVo.class);
        return contractInfoVos;
    }

    @Override
    public void signContract(SignContractDto signContractDto) {
        Integer incomingId = signContractDto.getIncomingId();
        String lockKey = CONTRACT_LOCK_KEY + incomingId;
        RLock lock = redissonClient.getLock(lockKey);
        try {
            log.info("尝试获取锁");
            if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {
                log.info("成功获取锁");
                IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
                String status = incomingInfo.getStatus();
                Integer outId = signContractDto.getOutId();
                if (signContractDto.getSignType().equals("0")) {
                    if (!status.equals(SysConstant.BUSINESS_STATUS_FIVE))
                        throw new XkdException("请勿重复签约");
                } else if (signContractDto.getSignType().equals("1")) {//再次签约
                    OutInfo outInfo = outInfoMapper.selectOne(new LambdaQueryWrapper<OutInfo>().eq(OutInfo::getOutId, outId));
                    if (!outInfo.getStatus().equals(SysConstant.BUSINESS_STATUS_SIX))
                        throw new XkdException("请勿重复签约");
                    //先删除
                    List<String> removeContracts = contractMapper.selectRemoveContracts(outId);
                    LambdaQueryWrapper<Contract> lqw = new LambdaQueryWrapper<>();
                    ArrayList<String> list = new ArrayList<>();
                    list.add(SysConstant.CONTRACT_TYPE_TOW);
                    list.add(SysConstant.CONTRACT_TYPE_THREE);
                    list.add(SysConstant.CONTRACT_TYPE_FIVE);
                    list.add(SysConstant.CONTRACT_TYPE_SIX);
                    list.add(SysConstant.CONTRACT_TYPE_SEVEN);
                    lqw.eq(Contract::getOutId, outId).in(Contract::getType, list);
                    contractMapper.delete(lqw);
                    fileService.filesRemove(removeContracts);

                    signContractDto.setRate(outInfo.getRate());
                    signContractDto.setTerm(outInfo.getTerm());
                    signContractDto.setLoanMethod(outInfo.getLoanMethod());
                    signContractDto.setLoanAmount(outInfo.getOutLoan());
                    signContractDto.setRepayFrequency(outInfo.getRepayFrequency());
                    signContractDto.setUsed(outInfo.getUsed());
                    signContractDto.setControversy(outInfo.getControversy());
                    signContractDto.setCityRemark(outInfo.getCityRemark());
                    signContractDto.setPayPass(outInfo.getPayPass());
                }

                //贷款合同
//        String dkcontract = borrowing(signContractDto);
                HashMap<String, String> contractMap = borrowing(signContractDto);
                String dkcontract = contractMap.get(SysConstant.CONTRACT_TYPE_TOW);
                //还款承诺函
                String hkclh = repaymentCommitmentLetter(signContractDto, dkcontract);
                //代扣协议
                String dkxy = withhold(signContractDto, dkcontract);
                //批量发起合同
                String idCard = incomingInfo.getIdCard();
                String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);


                /*
                 * 担保人
                 * */

                if (StringUtils.isNotEmpty(incomingInfo.getGuarantorName())) {
                    String guarantorIdCard = incomingInfo.getGuarantorIdCard();//担保人
                    String guarantorPhone = AESUtil.decrypt(incomingInfo.getGuarantorPhone(), aesKey);
                    ContractBatchSignInput c2 = new ContractBatchSignInput();
                    c2.setContractNos(Collections.singletonList(contractMap.get(SysConstant.CONTRACT_TYPE_FIVE)));
                    c2.setAccount(guarantorIdCard);
                    c2.setMobile(guarantorPhone);
                    c2.setIsNotice(1);
                    c2.setValidateType(3);//手写识别签名+短信签约（仅限个人）
                    netSignClient.batchSignByAccount(c2);
                }

                /*
                 * 主借人
                 * */
                ArrayList<String> contractNos = new ArrayList<>();
                contractNos.add(dkcontract);//借款合同
                contractNos.add(hkclh);//还款承诺函
                contractNos.add(dkxy);//代扣协议
                if (contractMap.containsKey(SysConstant.CONTRACT_TYPE_THREE))//抵押合同
                    contractNos.add(contractMap.get(SysConstant.CONTRACT_TYPE_THREE));
                if (contractMap.containsKey(SysConstant.CONTRACT_TYPE_FIVE))//担保合同
                    contractNos.add(contractMap.get(SysConstant.CONTRACT_TYPE_FIVE));

                ContractBatchSignInput c1 = new ContractBatchSignInput();
                c1.setContractNos(contractNos);
                c1.setAccount(idCard);
                c1.setMobile(userPhone);
                c1.setIsNotice(1);
                c1.setValidateType(3);//手写识别签名+短信签约（仅限个人）
                netSignClient.batchSignByAccount(c1);


                /*
                 * 共借人
                 * */
                List<IncomingCommonLoan> incomingCommonLoans = incomingCommonLoanMapper.selectList(new LambdaQueryWrapper<IncomingCommonLoan>().eq(IncomingCommonLoan::getIncomingId, incomingId));
                if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
                    ArrayList<String> contractNosCommonLoans = new ArrayList<>();
                    contractNosCommonLoans.add(dkcontract);//借款合同

                    if (contractMap.containsKey(SysConstant.CONTRACT_TYPE_THREE))//抵押合同
                        contractNosCommonLoans.add(contractMap.get(SysConstant.CONTRACT_TYPE_THREE));
                    if (contractMap.containsKey(SysConstant.CONTRACT_TYPE_FIVE))//担保合同
                        contractNosCommonLoans.add(contractMap.get(SysConstant.CONTRACT_TYPE_FIVE));

                    for (IncomingCommonLoan incomingCommonLoan : incomingCommonLoans) {
                        String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                        String card = incomingCommonLoan.getIdCard();
                        ContractBatchSignInput c3 = new ContractBatchSignInput();
                        c3.setContractNos(contractNosCommonLoans);
                        c3.setAccount(card);
                        c3.setMobile(decryptPhone);
                        c3.setIsNotice(1);
                        c3.setValidateType(3);//手写识别签名+短信签约（仅限个人）
                        netSignClient.batchSignByAccount(c3);
                    }
                }
            } else {
                throw new XkdException("服务器繁忙请稍后再试");
            }
        } catch (Exception e) {
            log.error("创建合同失败，请求参数: {}, 锁键: {}, 异常信息: {}", signContractDto, lockKey, e.getMessage(), e);
            throw new XkdException(e.getMessage());
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                log.info("创建合同释放锁，锁键: {}", lockKey);
            }
        }



    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<AddSignerVo> h5SignContract(Integer incomingId, String AmountDue, List<RepaymentInsuranceSchedule> repaymentInsuranceSchedules) {
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
//        String idCard = incomingInfo.getIdCard();
//        addStrangerV2(idCard);//添加陌生人
        AddSignerVo bdjkht = BDJKHT(incomingInfo, AmountDue, repaymentInsuranceSchedules);
        AddSignerVo wtdksqsht = WTDKSQSHT(incomingInfo);
        AddSignerVo wttbht = WTTBHT(incomingInfo);
        AddSignerVo flwssddzht = FLWSSDDZHT(incomingInfo, bdjkht.getContractNo(), wttbht.getContractNo());
        AddSignerVo tbsqs = TBSQS(incomingInfo, wttbht.getContractNo());
        //是否是个人，个人则批量签署
//        if (incomingInfo.getPrincipalType().equals("0")) {
//            ArrayList<String> contractNos = new ArrayList<>();
//            contractNos.add(bdjkht);
//            contractNos.add(flwssddzht);
//            contractNos.add(wtdksqsht);
//            contractNos.add(wttbht);
//            contractNos.add(tbsqs);
//
//            ContractBatchSignInput c1 = new ContractBatchSignInput();
//            c1.setContractNos(contractNos);
//            c1.setAccount(idCard);
//            c1.setMobile(AESUtil.decrypt(incomingInfo.getPhone(), aesKey));
//            c1.setIsNotice(1);
//            c1.setValidateType(3);//手写识别签名+短信签约（仅限个人）
//            netSignClient.batchSignByAccount(c1);
//        }
        return Arrays.asList(bdjkht, flwssddzht, wtdksqsht, wttbht, tbsqs);
    }


    @Override
    public HashMap<String, String> companyFace(Integer incomingId, String token) {
        //认证企业三要素实名认证  返回流水号与验证码
        CompanyAuthMobile3Dto companyAuthMobile3Dto = incomingInfoMapper.selectIncomingCompany(incomingId);
        AuthInput authInput = new AuthInput();
        authInput.setCompanyName(companyAuthMobile3Dto.getCompanyName());
        authInput.setCreditCode(companyAuthMobile3Dto.getCreditCode());
        authInput.setRealName(companyAuthMobile3Dto.getRealName());
        authInput.setIdCardNo(companyAuthMobile3Dto.getIdCardNo());
        String url = faceredirectUrl + "?token=" + token;
        authInput.setRedirectUrl(url);
        ApiRespBody<AuthOutput> authOutputApiRespBody = netSignClient.companyAuthFace(authInput);
        if (authOutputApiRespBody.getCode() != 100000)
            throw new XkdException("人脸识别失败：" + authOutputApiRespBody.getMsg());
        HashMap<String, String> map = new HashMap<>();
        map.put("faceUrl", authOutputApiRespBody.getData().getFaceUrl());//人脸识别链接
        map.put("serialNo", authOutputApiRespBody.getData().getSerialNo());//流水号
        map.put("principalType", SysConstant.PRINCIPAL_TYPE_ONE);//自然人/企业
        //流水号存入redis
        redisTemplate.opsForValue().set(serialNo + token, authOutputApiRespBody.getData().getSerialNo(), 60 * 60, TimeUnit.SECONDS);
        return map;
    }

    //添加用户
    @Override
    public void addPersonalUser(Integer incomingId, String serialNo) {

        //查询用户是否添加过
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        ApiRespBody<SignUserOutput> user = netSignClient.getUser(incomingInfo.getIdCard());
        if (user.getCode() == 100025) {
            log.info("用户不存在,执行添加个人用户，流水编号：" + serialNo);
            UserInput userInput = new UserInput();
            userInput.setAccount(incomingInfo.getIdCard());
            userInput.setSerialNo(serialNo);
            ApiRespBody body = netSignClient.addPersonalUserV2(userInput);
            int code = body.getCode();
            if (code == 100000) {
                log.info("用户添加成功");
            } else {
                throw new XkdException(body.getMsg());
            }
        } else if (user.getCode() == 100000) {
            log.info("用户已存在");
        }


    }

    @Override
    public void addCompany(Integer incomingId, String serialNo, String unifiedSocialCreditCode) {
        boolean companyIsAuth = getCompanyIsAuth(unifiedSocialCreditCode);
        if (companyIsAuth) {//已存在
            log.info("企业已存在");
            return;
        }
        CompanyAuthMobile3Dto companyAuthMobile3Dto = incomingInfoMapper.selectIncomingCompany(incomingId);
        VerifyCaptchaDto verifyCaptchaDto = new VerifyCaptchaDto();
        verifyCaptchaDto.setSerialNo(serialNo);
        verifyCaptchaDto.setCreditCode(companyAuthMobile3Dto.getCreditCode());
        verifyCaptchaDto.setMobile(AESUtil.decrypt(companyAuthMobile3Dto.getMobile(), aesKey));
        addEnterpriseUser(verifyCaptchaDto);
    }

    @Override
    public String insuranceCompanyAuthMobile3(CompanyAuthMobile3Dto companyAuthMobile3Dto) {
        companyAuthMobile3Dto.setMobile(AESUtil.decrypt(companyAuthMobile3Dto.getMobile(), aesKey));
        return authMobile3(companyAuthMobile3Dto);
    }

    @Override
    public void insuranceVerifyCaptcha(InsuranceVerifyCaptchaDto insuranceVerifyCaptchaDto) {
        VerifyCaptchaDto v = new VerifyCaptchaDto();
        v.setSerialNo(insuranceVerifyCaptchaDto.getSerialNo());
        v.setCaptcha(insuranceVerifyCaptchaDto.getCaptcha());
        //认证验证码 流水号
        String verify = verify(v);

        v.setCreditCode(insuranceVerifyCaptchaDto.getCreditCode());
        v.setSerialNo(verify);
        v.setMobile(AESUtil.decrypt(insuranceVerifyCaptchaDto.getMobile(), aesKey));
        addEnterpriseUser(v);
    }

    @Override
    public HashMap<String, String> face(Integer incomingId, String token) {
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        AuthInput authInput = new AuthInput();
        authInput.setRealName(incomingInfo.getName());
        authInput.setIdCardNo(incomingInfo.getIdCard());
        String url = faceredirectUrl + "?token=" + token;
        authInput.setRedirectUrl(url);
        ApiRespBody<AuthOutput> authOutputApiRespBody = netSignClient.personAuthFace(authInput);
        if (authOutputApiRespBody.getCode() != 100000)
            throw new XkdException("人脸识别失败：" + authOutputApiRespBody.getMsg());
        HashMap<String, String> map = new HashMap<>();
        map.put("faceUrl", authOutputApiRespBody.getData().getFaceUrl());//人脸识别链接
        map.put("serialNo", authOutputApiRespBody.getData().getSerialNo());//流水号
        map.put("principalType", SysConstant.PRINCIPAL_TYPE_ZERO);//自然人/企业
        redisTemplate.opsForValue().set(serialNo + token, authOutputApiRespBody.getData().getSerialNo(), 60 * 60, TimeUnit.SECONDS);
        return map;
    }


    @Override
    public boolean getCompanyIsAuth(String creditCode) {

        ApiRespBody<SignUserOutput> compUser = netSignClient.getCompUser(creditCode, null, null);
        if (compUser.getCode() != 100000)
            throw new XkdException("查询失败：" + compUser.getMsg());
        List<JSONObject> data = (List<JSONObject>) compUser.getData();
        if (CollectionUtils.isEmpty(data))
            return false;
        JSONObject jsonObject = data.get(0);
        Integer status = jsonObject.getInteger("status");
        return status.equals(1);
    }


    //车险分期-借款合同
    private AddSignerVo BDJKHT(IncomingInfo incomingInfo, String AmountDue, List<RepaymentInsuranceSchedule> repaymentInsuranceSchedules) {
        log.info("执行车险分期-借款合同");
        Integer incomingId = incomingInfo.getIncomingId();
        Credit credit = creditMapper.selectOne(new LambdaQueryWrapper<Credit>().eq(Credit::getIncomingId, incomingId));
        InsuranceCompanyInfo insuranceCompanyInfo = insuranceCompanyInfoMapper.selectById(incomingInfo.getInsuranceCompanyId());
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("借款协议");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            template.setTemplateNo(aqHtProperties.getGrcxfqjktemplate());
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            template.setTemplateNo(aqHtProperties.getCxfqjktemplate());
        }
        Map<String, String> map = new HashMap<>();
        map.put("ContractNumber", contractNo);
        String Name = "";
        String CardNumber = "";
        String Add = "";
        String ContactPerson = "";
        String ContactPhone = "";
        String ContactEmail = "";
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//自然人
            Name = incomingInfo.getName();
            CardNumber = incomingInfo.getIdCard();
            Add = incomingInfo.getAddress();
            ContactPerson = incomingInfo.getName();
            ContactPhone = incomingInfo.getPhone();
            ContactEmail = incomingInfo.getEmail();
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            Name = incomingInfo.getCompanyName();
            CardNumber = incomingInfo.getUnifiedSocialCreditCode();
            Add = incomingInfo.getCompanyAddress();
            if (incomingInfo.getSigningMethod().equals("0")) {//法人签约
                ContactPerson = incomingInfo.getLegalEntityName();
                ContactPhone = incomingInfo.getLegalPhone();
                ContactEmail = incomingInfo.getLegalEmail();
            } else if (incomingInfo.getSigningMethod().equals("1")) {//经办人签约
                ContactPerson = incomingInfo.getName();
                ContactPhone = incomingInfo.getPhone();
                ContactEmail = incomingInfo.getEmail();
            }
        }
        map.put("Name", Name);
        map.put("CardNumber", CardNumber);
        map.put("Add", Add);
        map.put("ContactPerson", ContactPerson);
        map.put("ContactPhone", AESUtil.decrypt(ContactPhone, aesKey));
        map.put("ContactEmail", ContactEmail);
        map.put("LoanAmount1", XkdUtil.number2CNMontrayUnit(credit.getLoanAmount()));
        map.put("LoanAmount2", String.valueOf(credit.getLoanAmount()));
        map.put("LoanTerm", String.valueOf(credit.getTerm()));
        map.put("RepaymentDate", String.valueOf(credit.getRepayDay()));

        String Interestrate = "";
        String Handlingfee1 = "";
        String Handlingfee2 = "";

        if (credit.getLoanMethod().equals(SysConstant.REPAY_TYPE_TWO)) {//等本等息
            if (credit.getChargeModel().equals(SysConstant.INSURANCE_FEE_TYPE_ZERO)) {
                Handlingfee1 = "0";
                Handlingfee2 = "0";
            } else if (credit.getChargeModel().equals(SysConstant.INSURANCE_FEE_TYPE_ONE)) {
                Handlingfee1 = String.valueOf(credit.getPostServiceFeeRate());
                Handlingfee2 = String.valueOf(credit.getPostServiceFeeRate());
            } else if (credit.getChargeModel().equals(SysConstant.INSURANCE_FEE_TYPE_TWO)) {
                Handlingfee1 = String.valueOf(credit.getPreServiceFeeRate());
                Handlingfee2 = String.valueOf(credit.getRate());
            }
        } else {
            Interestrate = String.valueOf(credit.getRate());
        }
        map.put("Interestrate", Interestrate);
        map.put("Handlingfee1", Handlingfee1);
        map.put("Handlingfee2", Handlingfee2);

        map.put("InsuranceName", insuranceCompanyInfo.getInsuranceCompanyName());
        map.put("countNumber", insuranceCompanyInfo.getOpeningBankAccount());
        map.put("OpeningBank", insuranceCompanyInfo.getOpeningBankName());
        String Option = "";
        if (credit.getLoanMethod().equals(SysConstant.REPAY_TYPE_ZERO)) {
            Option = "(3)";
        } else if (credit.getLoanMethod().equals(SysConstant.REPAY_TYPE_ONE)) {
            Option = "(2)";
        } else if (credit.getLoanMethod().equals(SysConstant.REPAY_TYPE_TWO)) {
            Option = "(4)";
        }
        map.put("Option", Option);
        map.put("LoanAmount3", String.valueOf(credit.getLoanAmount()));
        map.put("AnnualizedRate", String.valueOf(credit.getRate()));
        map.put("AmountDue", AmountDue);
        String ServiceFee = "0";
        if (!credit.getChargeModel().equals(SysConstant.INSURANCE_FEE_TYPE_ZERO)) {
            ServiceFee = String.valueOf(credit.getPostServiceFee());
        }
        map.put("ServiceFee", ServiceFee);
        if (CollectionUtils.isNotEmpty(repaymentInsuranceSchedules)) {
            for (int i = 1; i <= repaymentInsuranceSchedules.size(); i++) {
                RepaymentInsuranceSchedule repaymentInsuranceSchedule = repaymentInsuranceSchedules.get(i - 1);
                map.put("A" + i, String.valueOf(repaymentInsuranceSchedule.getInstallmentNumber()));
                map.put("B" + i, DateUtil.format(repaymentInsuranceSchedule.getRepaymentDate(), "yyyy-MM-dd"));
                map.put("C" + i, String.valueOf(repaymentInsuranceSchedule.getAmount()));
                map.put("D" + i, String.valueOf(repaymentInsuranceSchedule.getPrincipal()));
                map.put("E" + i, String.valueOf(repaymentInsuranceSchedule.getInterest()));
            }
        }
        map.put("LinkBankName", credit.getRepayName());
        map.put("LinkCountNumber", credit.getRepayAccount());
        map.put("LinkOpeningBank", credit.getRepayBank());
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        AddSignerVo addSignerVo = new AddSignerVo();
        addSignerVo.setContractNo(contractNo);
        addSignerVo.setPreviewUrl(previewUrl);
        addSignerVo.setContractType(SysConstant.CONTRACT_TYPE_TWELVE);
        addSignerVo.setContractName("借款合同");
        return addSignerVo;

    }

    @Override
    public void addSignerBDJKHT(Integer incomingId, String contractNo, IncomingInfo incomingInfo, Integer outId) {
        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();
        ContractUserInput c1 = new ContractUserInput();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getIdCard());
            c1.setSignType(2);

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) { //企业
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getUnifiedSocialCreditCode());
            c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        }
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("乙方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        Contract c = new Contract();
        c.setIncomingId(incomingId);
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_TWELVE);
        c.setStatus("1");
        c.setStartTime(new Date());
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setOutId(outId);
        c.setPreviewUrl(data.getPreviewUrl());

        contractMapper.insert(c);
    }

    //车险分期-法律文书送达地址确认书
    private AddSignerVo FLWSSDDZHT(IncomingInfo incomingInfo, String jkht, String wttbht) {
        log.info("执行车险分期-法律文书送达地址确认书");

        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("法律文书送达地址确认书");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            template.setTemplateNo(aqHtProperties.getGrflwstemplate());
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            template.setTemplateNo(aqHtProperties.getFlwstemplate());
        }
        Map<String, String> map = new HashMap<>();
        String name = "";
        String Tel = "";
        String Email = "";
        String Add = "";
        String IDType = "";
        String ID = "";
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//自然人
            name = incomingInfo.getName();
            Tel = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
            Email = incomingInfo.getEmail();
            Add = incomingInfo.getAddress();
            IDType = "身份证";
            ID = incomingInfo.getIdCard();
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            name = incomingInfo.getLegalEntityName();
            Tel = AESUtil.decrypt(incomingInfo.getLegalPhone(), aesKey);
            Email = incomingInfo.getLegalEmail();
            Add = incomingInfo.getCompanyAddress();
            IDType = "统一社会信用代码";
            ID = incomingInfo.getUnifiedSocialCreditCode();
        }
        map.put("LoanNumber", jkht);
        map.put("AgreementNumber", wttbht);
        map.put("name", name);
        map.put("Tel", Tel);
        map.put("Email", Email);
        map.put("Add", Add);
        map.put("IDType", IDType);
        map.put("ID", ID);

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        AddSignerVo addSignerVo = new AddSignerVo();
        addSignerVo.setContractNo(contractNo);
        addSignerVo.setPreviewUrl(previewUrl);
        addSignerVo.setContractType(SysConstant.CONTRACT_TYPE_THIRTEEN);
        addSignerVo.setContractName("法律文书送达地址确认书");
        return addSignerVo;
    }

    @Override
    public void addSignerFLWSSDDZHT(Integer incomingId, String contractNo, IncomingInfo incomingInfo, Integer outId) {
        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();
        ContractUserInput c1 = new ContractUserInput();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getIdCard());
            c1.setSignType(2);

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) { //企业
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getUnifiedSocialCreditCode());
            c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        }
        userInputList.add(c1);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        Contract c = new Contract();
        c.setIncomingId(incomingId);
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_THIRTEEN);
        c.setStatus("1");
        c.setStartTime(new Date());
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setOutId(outId);
        c.setPreviewUrl(data.getPreviewUrl());

        contractMapper.insert(c);
    }

    //车险分期-委托代扣授权书
    private AddSignerVo WTDKSQSHT(IncomingInfo incomingInfo) {
        log.info("执行车险分期-委托代扣授权书");
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("委托代扣授权书");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            template.setTemplateNo(aqHtProperties.getGrcxfqwtdktemplateNo());
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            template.setTemplateNo(aqHtProperties.getCxfqwtdktemplateNo());
        }
        Map<String, String> map = new HashMap<>();
        String name1 = "";
        String ID = "";
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//自然人
            name1 = incomingInfo.getName();
            ID = incomingInfo.getIdCard();
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            name1 = incomingInfo.getCompanyName();
            ID = incomingInfo.getUnifiedSocialCreditCode();
        }
        map.put("name1", name1);
        map.put("ID", ID);
        map.put("name2", "广东宝坤网络小额贷款有限公司");

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        AddSignerVo addSignerVo = new AddSignerVo();
        addSignerVo.setContractNo(contractNo);
        addSignerVo.setPreviewUrl(previewUrl);
        addSignerVo.setContractType(SysConstant.CONTRACT_TYPE_FOURTEEN);
        addSignerVo.setContractName("委托代扣授权书");
        return addSignerVo;
    }

    @Override
    public void addSignerWTDKSQSHT(IncomingInfo incomingInfo, String contractNo, Integer outId) {
        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();
        ContractUserInput c1 = new ContractUserInput();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getIdCard());
            c1.setSignType(2);
//            c1.setNoticeMobile(AESUtil.decrypt(incomingInfo.getPhone(), aesKey));
//            c1.setIsNotice(0);
//            c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) { //企业
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getUnifiedSocialCreditCode());
            c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        }
        userInputList.add(c1);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        Contract c = new Contract();
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_FOURTEEN);
        c.setStatus("1");
        c.setStartTime(new Date());
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setOutId(outId);
        c.setPreviewUrl(data.getPreviewUrl());

        contractMapper.insert(c);
    }


    //车险分期-委托投保合同
    private AddSignerVo WTTBHT(IncomingInfo incomingInfo) {
        log.info("执行车险分期-委托投保合同");
        Integer incomingId = incomingInfo.getIncomingId();
        Credit credit = creditMapper.selectOne(new LambdaQueryWrapper<Credit>().eq(Credit::getIncomingId, incomingId));
        InsuranceCompanyInfo insuranceCompanyInfo = insuranceCompanyInfoMapper.selectById(incomingInfo.getInsuranceCompanyId());
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("委托投保合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            template.setTemplateNo(aqHtProperties.getGrwttbtemplateNo());
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            template.setTemplateNo(aqHtProperties.getWttbtemplateNo());
        }
        Map<String, String> map = new HashMap<>();
        map.put("ContractNumber", contractNo);
        String Principal = "";
        String ID = "";
        String ContactPerson = "";
        String ContactTel = "";
        String ContactAdd = "";
        String ContactEmail = "";

        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//自然人
            Principal = incomingInfo.getName();
            ID = incomingInfo.getIdCard();
            ContactPerson = incomingInfo.getName();
            ContactTel = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
            ContactAdd = incomingInfo.getAddress();
            ContactEmail = incomingInfo.getEmail();
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            Principal = incomingInfo.getCompanyName();
            ID = incomingInfo.getUnifiedSocialCreditCode();
            ContactAdd = incomingInfo.getCompanyAddress();
            if (incomingInfo.getSigningMethod().equals("0")) {//法人签约
                ContactPerson = incomingInfo.getLegalEntityName();
                ContactTel = AESUtil.decrypt(incomingInfo.getLegalPhone(), aesKey);
                ContactEmail = incomingInfo.getLegalEmail();
            } else if (incomingInfo.getSigningMethod().equals("1")) {//经办人签约
                ContactPerson = incomingInfo.getName();
                ContactTel = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
                ContactEmail = incomingInfo.getEmail();
            }
        }
        BigDecimal otherAmount = credit.getOtherAmount() == null ? BigDecimal.ZERO : credit.getOtherAmount();
        BigDecimal posServiceFee = credit.getPostServiceFee() == null ? BigDecimal.ZERO : credit.getPostServiceFee();
        BigDecimal preServiceFee = credit.getPreServiceFee() == null ? BigDecimal.ZERO : credit.getPreServiceFee();
        map.put("Principal", Principal);
        map.put("ID", ID);
        map.put("ContactPerson", ContactPerson);
        map.put("ContactTel", ContactTel);
        map.put("ContactAdd", ContactAdd);
        map.put("ContactEmail", ContactEmail);
        map.put("Trustee", insuranceCompanyInfo.getInsuranceCompanyName());
        map.put("USCC", insuranceCompanyInfo.getUnifiedSocialCreditCode());
        map.put("Add", insuranceCompanyInfo.getBusinessAddress());
        map.put("AccountID", insuranceCompanyInfo.getOpeningBankAccount());
        map.put("BankofDeposit", insuranceCompanyInfo.getOpeningBankName());
        map.put("Proxypayment", String.valueOf(credit.getInsuranceAmount().add(otherAmount)));
        map.put("Insurancecost", String.valueOf(credit.getInsuranceAmount()));
        map.put("Othercosts", String.valueOf(otherAmount));
        map.put("ratio", String.valueOf(credit.getDownRepaymentRate()));
        map.put("Downpayment", String.valueOf(credit.getDownRepaymentAmount()));
        BigDecimal add = preServiceFee.add(posServiceFee);
        map.put("Money", String.valueOf(add));
        template.setFillData(map);

        //表格
        List<CarCredit> carCredits = carCreditMapper.selectList(new LambdaQueryWrapper<CarCredit>().eq(CarCredit::getIncomingId, incomingId));
        if (CollectionUtils.isNotEmpty(carCredits)) {
            List<ComponentTableDTO> tableDatas = new ArrayList<>();
            ComponentTableDTO componentTableDTO = new ComponentTableDTO();
            componentTableDTO.setKeyword("表格1");

            List<TableRowDTO> rowValues = new ArrayList<>();
            String accountName = credit.getAccountName();
            String insuranceCompanyName = insuranceCompanyInfo.getInsuranceCompanyName();
            String insuranceType = credit.getInsuranceType();
            if (insuranceType.equals("0")) {
                insuranceType = "车险";
            } else if (insuranceType.equals("1")) {
                insuranceType = "工程机械保险";
            }
            for (int i = 1; i <= carCredits.size(); i++) {
                CarCredit carCredit = carCredits.get(i - 1);
                BigDecimal amount = carCredit.getAmount();
                TableRowDTO rowValue = new TableRowDTO();
                rowValue.setInsertRow(true);
                ArrayList<String> l1 = new ArrayList<>();
                l1.add(String.valueOf(i));
                l1.add(accountName);
                l1.add(insuranceCompanyName);
                l1.add(insuranceType);
                l1.add(String.valueOf(amount));
                l1.add(credit.getInsuredName());
                l1.add(carCredit.getCarNo());
                l1.add(carCredit.getVin());
                l1.add(carCredit.getMotorNo());
                rowValue.setColValues(l1);
                rowValues.add(rowValue);
            }
            componentTableDTO.setRowValues(rowValues);
            tableDatas.add(componentTableDTO);
            template.setTableDatas(tableDatas);
        }

        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        AddSignerVo addSignerVo = new AddSignerVo();
        addSignerVo.setContractType(SysConstant.CONTRACT_TYPE_FIFTEEN);
        addSignerVo.setPreviewUrl(previewUrl);
        addSignerVo.setContractNo(contractNo);
        addSignerVo.setContractName("委托投保合同");
        return addSignerVo;
    }

    @Override
    public void addSignerWTTBHT(IncomingInfo incomingInfo, String contractNo, InsuranceCompanyInfo insuranceCompanyInfo, Integer outId) {
        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();
        ContractUserInput c1 = new ContractUserInput();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getIdCard());
            c1.setSignType(2);
//            c1.setNoticeMobile(AESUtil.decrypt(incomingInfo.getPhone(), aesKey));
//            c1.setIsNotice(0);
//            c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) { //企业
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getUnifiedSocialCreditCode());
            c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章
            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        }
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("乙方一");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        /*
         * 投保公司
         * */
        ContractUserInput c3 = new ContractUserInput();
        c3.setContractNo(contractNo);
        c3.setAccount(insuranceCompanyInfo.getUnifiedSocialCreditCode());
        c3.setSignType(2);//无感签约

        List<UserSignStrategyInput> s3 = new ArrayList<>(5);
        UserSignStrategyInput u3 = new UserSignStrategyInput();
        u3.setAttachNo(1);
        u3.setLocationMode(4);
        u3.setSignKey("乙方二");
        s3.add(u3);
        c3.setSignStrategyList(s3);


        userInputList.add(c1);
        userInputList.add(c2);
        userInputList.add(c3);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        Contract c = new Contract();
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_FIFTEEN);
        c.setStatus("1");
        c.setStartTime(new Date());
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setOutId(outId);
        c.setPreviewUrl(data.getPreviewUrl());

        contractMapper.insert(c);
    }

    private AddSignerVo TBSQS(IncomingInfo incomingInfo, String wttbht) {
        log.info("执行车险分期-退保授权书");
        Integer incomingId = incomingInfo.getIncomingId();
        InsuranceCompanyInfo insuranceCompanyInfo = insuranceCompanyInfoMapper.selectById(incomingInfo.getInsuranceCompanyId());
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("退保授权书");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            template.setTemplateNo(aqHtProperties.getGrtbsqtemplateNo());
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            template.setTemplateNo(aqHtProperties.getTbsqtemplateNo());
        }
        Map<String, String> map = new HashMap<>();

        map.put("Authorizer", "广东宝坤网络小额贷款有限公司");
        map.put("Policyholder", insuranceCompanyInfo.getInsuranceCompanyName());
        map.put("TBContractNumber", wttbht);
        String AuthorizerNumber = "";
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//自然人
            AuthorizerNumber = incomingInfo.getIdCard();
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) {//企业
            AuthorizerNumber = incomingInfo.getUnifiedSocialCreditCode();
        }
        map.put("AuthorizerNumber", AuthorizerNumber);
        template.setFillData(map);
        //表格
        List<CarCredit> carCredits = carCreditMapper.selectList(new LambdaQueryWrapper<CarCredit>().eq(CarCredit::getIncomingId, incomingId));
        if (CollectionUtils.isNotEmpty(carCredits)) {
            List<ComponentTableDTO> tableDatas = new ArrayList<>();
            ComponentTableDTO componentTableDTO = new ComponentTableDTO();
            componentTableDTO.setKeyword("表格1");

            List<TableRowDTO> rowValues = new ArrayList<>();
            for (int i = 1; i <= carCredits.size(); i++) {
                CarCredit carCredit = carCredits.get(i - 1);
                TableRowDTO rowValue = new TableRowDTO();
                rowValue.setInsertRow(true);
                ArrayList<String> l1 = new ArrayList<>();
                l1.add(String.valueOf(i));
                l1.add(carCredit.getCarNo());
                l1.add(carCredit.getVin());
                l1.add(carCredit.getMotorNo());
                rowValue.setColValues(l1);
                rowValues.add(rowValue);
            }
            componentTableDTO.setRowValues(rowValues);
            tableDatas.add(componentTableDTO);
            template.setTableDatas(tableDatas);
        }

        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        AddSignerVo addSignerVo = new AddSignerVo();
        addSignerVo.setPreviewUrl(previewUrl);
        addSignerVo.setContractNo(contractNo);
        addSignerVo.setContractType(SysConstant.CONTRACT_TYPE_SIXTEEN);
        addSignerVo.setContractName("退保授权书");
        return addSignerVo;
    }

    @Override
    public void addsignerTBSQS(IncomingInfo incomingInfo, String contractNo, Integer outId) {

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();
        ContractUserInput c1 = new ContractUserInput();
        if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ZERO)) {//个人
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getIdCard());
            c1.setSignType(2);

            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        } else if (incomingInfo.getPrincipalType().equals(SysConstant.PRINCIPAL_TYPE_ONE)) { //企业
            c1.setContractNo(contractNo);
            c1.setAccount(incomingInfo.getUnifiedSocialCreditCode());
            c1.setSignType(2);//无感签约
            List<UserSignStrategyInput> s1 = new ArrayList<>(5);
            UserSignStrategyInput u1 = new UserSignStrategyInput();
            u1.setAttachNo(1);
            u1.setLocationMode(4);
            u1.setSignKey("甲方");
            s1.add(u1);
            c1.setSignStrategyList(s1);
        }

        userInputList.add(c1);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        Contract c = new Contract();
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_SIXTEEN);
        c.setStatus("1");
        c.setStartTime(new Date());
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setOutId(outId);
        c.setPreviewUrl(data.getPreviewUrl());

        contractMapper.insert(c);
    }

    @Override
    public void companyContractNotifyUrl(QMHD qmhd) throws InterruptedException {
        LambdaQueryWrapper<CompanyContract> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CompanyContract::getContractOrder, qmhd.getContractNo());
        CompanyContract contract = null;
        for (int i = 1; i <= maxRetry; i++) {
            contract = companyContractMapper.selectOne(lqw);
            log.info("第 {} 次查询合同数据：{}", i, contract);
            if (contract != null)
                break;
            try {
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                log.warn("等待过程中被中断", e);
                Thread.currentThread().interrupt(); // 恢复中断状态
                break;
            }
        }
        if (contract == null) {
            log.error("重试 {} 次后仍未获取到合同数据", maxRetry);
            throw new RuntimeException("未获取到合同数据，请稍后再试");
        }
        String baseUrl = localPathDir + contractUrl + "/" + contract.getCompanyId() + "/";
        String filePath = qmhd.getContractNo() + ".pdf";
        String fileUrl = baseUrl + filePath;//文件下载路径
        File dirFile = new File(baseUrl);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        ApiRespBody<DownloadContractOutput> body = netSignClient.downloadContract(qmhd.getContractNo(), 1, fileUrl);
        int code = body.getCode();
        if (code != 100000) {
            throw new XkdException(body.getMsg());
        }

        LambdaQueryWrapper<CompanyContract> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(CompanyContract::getContractOrder, qmhd.getContractNo());
        CompanyContract c = new CompanyContract();
        c.setUrl(contractUrl + "/" + contract.getCompanyId() + "/" + filePath);
        c.setContractTime(DateUtil.parse(qmhd.getSignTime()));
        c.setStatus("2");
        companyContractMapper.update(c, lqw2);
        if (contract.getType().equals(SysConstant.COMPANY_CONTRACT_TYPE_ONE))
            //修改公司表签署状态
            companyMapper.updateContractStatus(contract.getCompanyId(), SysConstant.CONTRACT_DO);

    }

    private HashMap<String, Object> notarizationBorrowing(SignContractDto signContractDto) {
        ArrayList<Proposer> proposers = new ArrayList<>();
        String contractName = "贷款合同";
//        List<RoleInfo> roleInfos = new ArrayList<>();
        HashMap<String, Object> resultMap = new HashMap<>();
        List<NotarizationContractVo> notarizationContractVos = new ArrayList<>();
        ArrayList<String> productTypes = new ArrayList<>();
        productTypes.add(SysConstant.PRODUCT_TWO);
        productTypes.add(SysConstant.PRODUCT_THREE);
        Date contractCreate = new Date();
        Integer incomingId = signContractDto.getIncomingId();
        BigDecimal loanAmount = signContractDto.getLoanAmount();
        //查询进件信息
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        OutInfo outInfo = outInfoMapper.selectById(signContractDto.getOutId());
        if (incomingInfo.getStatus().equals(SysConstant.BUSINESS_STATUS_SEVEN))
            throw new XkdException("业务已签约完成，无需再次签约");
        String incomingPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        String Add = cityInfoMapper.selectAddress(incomingInfo.getProvince(), incomingInfo.getCity());
        Credit credit = creditMapper.selectOne(new LambdaQueryWrapper<Credit>().eq(Credit::getIncomingId, incomingId));
        Product product = productMapper.selectById(incomingInfo.getProductId());
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();//贷款合同编号
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName(contractName);
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getGZjkhttemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1Address", incomingInfo.getAddress());
        map.put("Y1Phone", incomingPhone);
        map.put("Y1Email", incomingInfo.getEmail());
        //判断是否有共借人
        List<IncomingCommonLoan> incomingCommonLoans = incomingCommonLoanMapper.selectList(new LambdaQueryWrapper<IncomingCommonLoan>().eq(IncomingCommonLoan::getIncomingId, incomingId));
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {

                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();

                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "CardId", card);
                map.put("Y" + i + "Address", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());

                /*
                 * 关系人信息
                 * 借款人
                 * */
                Proposer p1 = new Proposer();
                List<RoleInfo> roleInfos = new ArrayList<>();
                RoleInfo r1 = new RoleInfo();
                r1.setRoleCode("jkr");
                r1.setSort(i);
                roleInfos.add(r1);
                if (productTypes.contains(product.getType()) || (product.getType().equals(SysConstant.PRODUCT_FOUR) && incomingInfo.getIsJydMortgage().equals("1"))) {
                    RoleInfo r2 = new RoleInfo();
                    r2.setRoleCode("dyr");
                    r2.setSort(i);
                    roleInfos.add(r2);
                }
                p1.setRoleInfo(roleInfos);
                p1.setProposerId(String.valueOf(i));
                p1.setName(incomingCommonLoan.getName());
                p1.setMobile(decryptPhone);
                p1.setCardNum(card);
                p1.setDetailAddress(incomingCommonLoan.getAddress());
                p1.setEmail(incomingCommonLoan.getMail());
                ArrayList<ProposerMaterial> proposerMaterials = new ArrayList<>();
                ProposerMaterial pr1 = new ProposerMaterial();
                pr1.setFileCode("100002-001");
                String idCardFrontUrl = incomingCommonLoan.getIdCardFrontUrl();
                pr1.setFileUrl(localUrlPath + incomingCommonLoan.getIdCardFrontUrl());
                pr1.setFileName(idCardFrontUrl.substring(idCardFrontUrl.lastIndexOf("/") + 1));
                ProposerMaterial pr2 = new ProposerMaterial();
                pr2.setFileCode("100002-002");
                String idCardReverseUrl = incomingCommonLoan.getIdCardReverseUrl();
                pr2.setFileUrl(localUrlPath + incomingCommonLoan.getIdCardReverseUrl());
                pr2.setFileName(idCardReverseUrl.substring(idCardReverseUrl.lastIndexOf("/") + 1));
                proposerMaterials.add(pr1);
                proposerMaterials.add(pr2);
                p1.setProposerMaterial(proposerMaterials);
                proposers.add(p1);

            }
        }
        map.put("Purpose", signContractDto.getUsed());
        map.put("CapitalRMB", XkdUtil.number2CNMontrayUnit(loanAmount));
        map.put("RMB", String.valueOf(loanAmount));
        String M = "";
        String EndTime = "";
        String StartTime = DateUtil.format(new Date(), "yyyy-MM-dd");
        Integer term = signContractDto.getTerm();
        if (signContractDto.getRepayFrequency().equals("1")) {//月
            M = term + "个月";
            EndTime = DateUtil.format(DateUtil.offsetMonth(new Date(), term), "yyyy-MM-dd");
        } else if (signContractDto.getRepayFrequency().equals("0")) {//天
            M = term + "天";
            EndTime = DateUtil.format(DateUtil.offsetDay(new Date(), term), "yyyy-MM-dd");
        } else {
            M = term + "周";
            EndTime = DateUtil.format(DateUtil.offsetWeek(new Date(), term), "yyyy-MM-dd");
        }
        map.put("M", M);
        map.put("StartTime", StartTime);
        map.put("EndTime", EndTime);
        map.put("A1", String.valueOf(signContractDto.getRate()));
        map.put("Y1NameEnter", credit.getAccountName());
        map.put("Y1BankEnter", credit.getBank());
        map.put("Y1BankCardEnter", credit.getReceivingAccount());
        String A2 = "";
        switch (signContractDto.getLoanMethod()) {
            case SysConstant.REPAY_TYPE_ZERO:
                A2 = "(2)";
                break;
            case SysConstant.REPAY_TYPE_ONE:
                A2 = "(1)";
                break;
            case SysConstant.REPAY_TYPE_TWO:
                A2 = "(4)";
                break;
            case SysConstant.REPAY_TYPE_THREE:
                A2 = "(5)";
                break;
            case SysConstant.REPAY_TYPE_FOUR:
                A2 = "(3)";
                break;
        }
        map.put("A2", A2);
        if (outInfo.getPayPass().equals(SysConstant.CHANNEL_TYPE_ONE)) {//通道一
            map.put("JBankCard", loans_in_account_offline);//小贷账号
        } else if (outInfo.getPayPass().equals(SysConstant.CHANNEL_TYPE_TWO)) {//通道二
            map.put("JBankCard", tow_loans_in_account_offline);//小贷账号
        }

        map.put("Y1NameOut", credit.getRepayName());
        map.put("Y1BankOut", credit.getRepayBank());
        map.put("Y1BankCardOut", credit.getRepayAccount());

        //判断有无担保人
        if (StringUtils.isNotEmpty(incomingInfo.getGuarantorName())) {
            //生成担保合同编号
            String dbcontractNo = OrderNumUtil.getContractNo();//担保合同编号
            map.put("GName", incomingInfo.getGuarantorName());
            map.put("GContractId", dbcontractNo);
            String contractUrl = notarizationGuarantee(incomingInfo, contractNo, dbcontractNo, Add, incomingCommonLoans, signContractDto);
            NotarizationContractVo notarizationContractVo = new NotarizationContractVo();
            notarizationContractVo.setContractNo(dbcontractNo);
            notarizationContractVo.setContractType(SysConstant.CONTRACT_TYPE_FIVE);
            notarizationContractVo.setContractUrl(contractUrl);
            notarizationContractVo.setContractName(contractUrl.substring(contractUrl.lastIndexOf("/") + 1));
            notarizationContractVo.setFileCode("1040");

            notarizationContractVos.add(notarizationContractVo);
            /*
             * 关系人信息
             * 担保人
             * */
            Proposer p1 = new Proposer();
            List<RoleInfo> roleInfos = new ArrayList<>();
            RoleInfo r1 = new RoleInfo();
            r1.setRoleCode("bzr");
            r1.setSort(1);
            roleInfos.add(r1);

            p1.setRoleInfo(roleInfos);
            p1.setProposerId("db");
            p1.setName(incomingInfo.getGuarantorName());
            p1.setMobile(AESUtil.decrypt(incomingInfo.getGuarantorPhone(), aesKey));
            p1.setCardNum(incomingInfo.getGuarantorIdCard());
            p1.setDetailAddress(incomingInfo.getGuarantorAddress());
            p1.setEmail(incomingInfo.getGuarantorMail());
            ArrayList<ProposerMaterial> proposerMaterials = new ArrayList<>();
            ProposerMaterial pr1 = new ProposerMaterial();
            pr1.setFileCode("100002-001");
            String guarantorIdCardFront = incomingInfo.getGuarantorIdCardFront();
            pr1.setFileUrl(localUrlPath + incomingInfo.getGuarantorIdCardFront());
            pr1.setFileName(guarantorIdCardFront.substring(guarantorIdCardFront.lastIndexOf("/") + 1));
            ProposerMaterial pr2 = new ProposerMaterial();
            pr2.setFileCode("100002-002");
            String guarantorIdCardReverse = incomingInfo.getGuarantorIdCardReverse();
            pr2.setFileUrl(localUrlPath + incomingInfo.getGuarantorIdCardReverse());
            pr2.setFileName(guarantorIdCardReverse.substring(guarantorIdCardReverse.lastIndexOf("/") + 1));
            proposerMaterials.add(pr1);
            proposerMaterials.add(pr2);
            p1.setProposerMaterial(proposerMaterials);
            proposers.add(p1);
        }
        //判断产品类型有无抵押
        ArrayList<MortgageInfo> carMortgageInfo = new ArrayList<>();
        if (productTypes.contains(product.getType()) || (product.getType().equals(SysConstant.PRODUCT_FOUR) && incomingInfo.getIsJydMortgage().equals("1"))) {
            //生成抵押合同编号
            String dycontractNo = OrderNumUtil.getContractNo();//抵押合同编号
            map.put("MName", incomingInfo.getName());
            map.put("MContractId", dycontractNo);

            String contractUrl = "";
            if (product.getType().equals(SysConstant.PRODUCT_TWO)) {    //车抵
                NotarizationCarmortgageVo result = notarizationCarmortgage(incomingId, contractNo, dycontractNo, incomingInfo, incomingCommonLoans, loanAmount, Add, signContractDto.getOutId());
                contractUrl = result.getFileUrl();
                //车辆抵押信息用于公证
                carMortgageInfo = result.getMortgageInfos();
            } else if (product.getType().equals(SysConstant.PRODUCT_THREE) || product.getType().equals(SysConstant.PRODUCT_FOUR)) {//房抵
                contractUrl = notarizationRoommortgage(incomingId, contractNo, dycontractNo, incomingInfo, incomingCommonLoans, loanAmount, Add, signContractDto.getOutId());
            }
            NotarizationContractVo notarizationContractVo = new NotarizationContractVo();
            notarizationContractVo.setContractNo(dycontractNo);
            notarizationContractVo.setContractType(SysConstant.CONTRACT_TYPE_THREE);
            notarizationContractVo.setContractUrl(contractUrl);
            notarizationContractVo.setContractName(contractUrl.substring(contractUrl.lastIndexOf("/") + 1));
            notarizationContractVo.setFileCode("1030");

            notarizationContractVos.add(notarizationContractVo);
        }
        String A4 = "";
        switch (signContractDto.getControversy()) {
            case SysConstant.CONTROVERSY_ONE:
                A4 = "3";
                break;
            case SysConstant.CONTROVERSY_TOW:
                A4 = "2";
                break;
            case SysConstant.CONTROVERSY_THREE:
                A4 = "1";
                break;
        }

        map.put("A4", A4);
        map.put("ArbitratAddress", signContractDto.getCityRemark());
//        map.put("Add", Add);
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        //下载贷款合同
        String s = downloadContract(contractNo, incomingInfo.getCompanyId());
        //保存签约合同信息
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_TOW);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(contractName);
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setContract(s);
        c.setPreviewUrl(previewUrl);
        c.setOutId(signContractDto.getOutId());
        contractMapper.insert(c);

        NotarizationContractVo notarizationContractVo = new NotarizationContractVo();
        notarizationContractVo.setContractNo(contractNo);
        notarizationContractVo.setContractType(SysConstant.CONTRACT_TYPE_TOW);
        notarizationContractVo.setContractUrl(localUrlPath + s);
        notarizationContractVo.setContractName(s.substring(s.lastIndexOf("/") + 1));
        notarizationContractVo.setFileCode("1020");
        notarizationContractVos.add(notarizationContractVo);
        resultMap.put("DKContractNo", contractNo);//合同编号
        resultMap.put("notarizationContractVos", notarizationContractVos);//合同信息
        /*
         * 关系人信息
         * 贷款方
         * */
        Proposer dkf = new Proposer();
        List<RoleInfo> dkfroleInfos = new ArrayList<>();
        RoleInfo dkfr = new RoleInfo();
        dkfr.setRoleCode("dkf");
        dkfr.setSort(1);
        dkfroleInfos.add(dkfr);
        dkf.setRoleInfo(dkfroleInfos);
        dkf.setProposerId("dkf");
        dkf.setOrganizationCardNum(organizationCardNum);
        dkf.setOrganizationName(organizationName);
        dkf.setOrganizationAddress(organizationAddress);
        dkf.setOrganizationPhone(organizationPhone);
        dkf.setName(name);
        ArrayList<ProposerMaterial> dkfproposerMaterials = new ArrayList<>();
        ProposerMaterial dkfpr1 = new ProposerMaterial();
        dkfpr1.setFileCode("100002-001");
        dkfpr1.setFileUrl(sfzzm);
        dkfpr1.setFileName(sfzzm.substring(sfzzm.lastIndexOf("/") + 1));
        ProposerMaterial dkfpr2 = new ProposerMaterial();
        dkfpr2.setFileCode("100002-002");
        dkfpr2.setFileUrl(sfzfm);
        dkfpr2.setFileName(sfzfm.substring(sfzfm.lastIndexOf("/") + 1));
        ProposerMaterial dkfpr3 = new ProposerMaterial();
        dkfpr3.setFileCode("100004");
        dkfpr3.setFileUrl(yyzzurl);
        dkfpr3.setFileName(yyzzurl.substring(yyzzurl.lastIndexOf("/") + 1));
        ProposerMaterial dkfpr4 = new ProposerMaterial();
        dkfpr4.setFileCode("100030");
        dkfpr4.setFileUrl(fddbrzmurl);
        dkfpr4.setFileName(fddbrzmurl.substring(fddbrzmurl.lastIndexOf("/") + 1));
        dkfproposerMaterials.add(dkfpr1);
        dkfproposerMaterials.add(dkfpr2);
        dkfproposerMaterials.add(dkfpr3);
        dkfproposerMaterials.add(dkfpr4);
        dkf.setProposerMaterial(dkfproposerMaterials);
        proposers.add(dkf);

        /*
         * 关系人信息
         * 借款人
         * */
        Proposer p1 = new Proposer();
        List<RoleInfo> jkrroleInfos = new ArrayList<>();
        RoleInfo r1 = new RoleInfo();
        r1.setRoleCode("jkr");
        r1.setSort(1);
        jkrroleInfos.add(r1);
        if (productTypes.contains(product.getType()) || (product.getType().equals(SysConstant.PRODUCT_FOUR) && incomingInfo.getIsJydMortgage().equals("1"))) {
            RoleInfo r2 = new RoleInfo();
            r2.setRoleCode("dyr");
            r2.setSort(1);
            jkrroleInfos.add(r2);
        }
        p1.setRoleInfo(jkrroleInfos);
        p1.setProposerId("1");
        p1.setName(incomingInfo.getName());
        p1.setMobile(incomingPhone);
        p1.setCardNum(incomingInfo.getIdCard());
        p1.setDetailAddress(incomingInfo.getAddress());
        p1.setEmail(incomingInfo.getEmail());
        ArrayList<ProposerMaterial> proposerMaterials = new ArrayList<>();
        ProposerMaterial pr1 = new ProposerMaterial();
        pr1.setFileCode("100002-001");
        String idCardFrontUrl = incomingInfo.getIdCardFrontUrl();
        pr1.setFileUrl(localUrlPath + incomingInfo.getIdCardFrontUrl());
        pr1.setFileName(idCardFrontUrl.substring(idCardFrontUrl.lastIndexOf("/") + 1));
        ProposerMaterial pr2 = new ProposerMaterial();
        pr2.setFileCode("100002-002");
        String idCardReverseUrl = incomingInfo.getIdCardReverseUrl();
        pr2.setFileUrl(localUrlPath + incomingInfo.getIdCardReverseUrl());
        pr2.setFileName(idCardReverseUrl.substring(idCardReverseUrl.lastIndexOf("/") + 1));
        proposerMaterials.add(pr1);
        proposerMaterials.add(pr2);
        p1.setProposerMaterial(proposerMaterials);
        proposers.add(p1);
        resultMap.put("proposers", proposers);//关系人信息
        ArrayList<LoadInfo> loadInfos = new ArrayList<>();
        LoadInfo loadInfo = new LoadInfo();
        loadInfo.setPurpose(signContractDto.getUsed());
        loadInfo.setAmount(loanAmount);
        loadInfo.setTerm(M);
        loadInfo.setStartDate(StartTime);
        loadInfo.setMaturityDate(EndTime);
        loadInfo.setRate(signContractDto.getRate() + "%");
        loadInfos.add(loadInfo);
        resultMap.put("loadInfo", loadInfos);//借款信息
        resultMap.put("carMortgageInfo", carMortgageInfo);//车辆抵押信息
        return resultMap;
    }

    @Override
    public HashMap<String, String> borrowing(SignContractDto signContractDto) {
        HashMap<String, String> contractMap = new HashMap<>();
        Date contractCreate = new Date();
        Integer incomingId = signContractDto.getIncomingId();
        BigDecimal loanAmount = signContractDto.getLoanAmount();
        String payPass = signContractDto.getPayPass();
//        Contract oldContract = checkContractInfo(id, SysConstant.CONTRACT_TYPE_TOW);
        //查询进件信息
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        if (incomingInfo.getStatus().equals(SysConstant.BUSINESS_STATUS_SEVEN))
            throw new XkdException("业务已签约完成，无需再次签约");
        String Add = null;
        if (incomingInfo.getCity() == null) {
            Add = signContractDto.getCity();
        } else {
            Add = cityInfoMapper.selectAddress(incomingInfo.getProvince(), incomingInfo.getCity());
        }
        Credit credit = creditMapper.selectOne(new LambdaQueryWrapper<Credit>().eq(Credit::getIncomingId, incomingId));
        Product product = productMapper.selectById(incomingInfo.getProductId());
        String idCard = incomingInfo.getIdCard();
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        //添加陌生用户
        addStrangerV2(idCard);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();//贷款合同编号
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("贷款合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getJkhttemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1Address", incomingInfo.getAddress());
        map.put("Y1Phone", AESUtil.decrypt(incomingInfo.getPhone(), aesKey));
        map.put("Y1Email", incomingInfo.getEmail());
        //判断是否有共借人
        List<IncomingCommonLoan> incomingCommonLoans = incomingCommonLoanMapper.selectList(new LambdaQueryWrapper<IncomingCommonLoan>().eq(IncomingCommonLoan::getIncomingId, incomingId));
        List<ContractUserInput> userInputList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {

                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();
                //添加陌生用户
                addStrangerV2(card);

                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "CardId", card);
                map.put("Y" + i + "Address", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());

                //添加共借人签署方
                ContractUserInput c = new ContractUserInput();
                c.setContractNo(contractNo);
                c.setAccount(card);
                c.setSignType(3);
                c.setNoticeMobile(decryptPhone);
                c.setIsNotice(0);
                c.setValidateType(6);//手写识别签名+短信签约（仅限个人）

                List<UserSignStrategyInput> s = new ArrayList<>(5);
                UserSignStrategyInput u = new UserSignStrategyInput();
                u.setAttachNo(1);
                u.setLocationMode(4);
                u.setSignKey("乙方" + i);
                s.add(u);
                c.setSignStrategyList(s);
                userInputList.add(c);
            }
        }
        map.put("Purpose", signContractDto.getUsed());
        map.put("CapitalRMB", XkdUtil.number2CNMontrayUnit(loanAmount));
        map.put("RMB", String.valueOf(loanAmount));
        String M = "";
        String EndTime = "";
        Integer term = signContractDto.getTerm();
        if (signContractDto.getRepayFrequency().equals("1")) {//月
            M = term + "个月";
            EndTime = DateUtil.format(DateUtil.offsetMonth(new Date(), term), "yyyy-MM-dd");
        } else if (signContractDto.getRepayFrequency().equals("0")) {//天
            M = term + "天";
            EndTime = DateUtil.format(DateUtil.offsetDay(new Date(), term), "yyyy-MM-dd");
        } else {
            M = term + "周";
            EndTime = DateUtil.format(DateUtil.offsetWeek(new Date(), term), "yyyy-MM-dd");
        }
        map.put("M", M);
        map.put("StartTime", DateUtil.format(new Date(), "yyyy-MM-dd"));
        map.put("EndTime", EndTime);
        map.put("A1", String.valueOf(signContractDto.getRate()));
        map.put("Y1NameEnter", credit.getAccountName());
        map.put("Y1BankEnter", credit.getBank());
        map.put("Y1BankCardEnter", credit.getReceivingAccount());
        String A2 = "";
        switch (signContractDto.getLoanMethod()) {
            case SysConstant.REPAY_TYPE_ZERO:
                A2 = "(2)";
                break;
            case SysConstant.REPAY_TYPE_ONE:
                A2 = "(1)";
                break;
            case SysConstant.REPAY_TYPE_TWO:
                A2 = "(4)";
                break;
            case SysConstant.REPAY_TYPE_THREE:
                A2 = "(5)";
                break;
            case SysConstant.REPAY_TYPE_FOUR:
                A2 = "(3)";
                break;
        }
        map.put("A2", A2);
        if (payPass.equals(SysConstant.CHANNEL_TYPE_ONE)) {//通道一
            map.put("JBankCard", loans_in_account_offline);//小贷账号
        } else if (payPass.equals(SysConstant.CHANNEL_TYPE_TWO)) {//通道二
            map.put("JBankCard", tow_loans_in_account_offline);//小贷账号
        }

        map.put("Y1NameOut", credit.getRepayName());
        map.put("Y1BankOut", credit.getRepayBank());
        map.put("Y1BankCardOut", credit.getRepayAccount());

        //判断有无担保人
        if (StringUtils.isNotEmpty(incomingInfo.getGuarantorName())) {
            //生成担保合同编号
            String dbcontractNo = OrderNumUtil.getContractNo();//担保合同编号
            map.put("GName", incomingInfo.getGuarantorName());
            map.put("GContractId", dbcontractNo);
            iAsyncService.guarantee(credit, incomingInfo, contractNo, dbcontractNo, Add, incomingCommonLoans, signContractDto);
            contractMap.put(SysConstant.CONTRACT_TYPE_FIVE, dbcontractNo);
        }
        //判断产品类型有无抵押
        ArrayList<String> productTypes = new ArrayList<>();
        productTypes.add(SysConstant.PRODUCT_TWO);
        productTypes.add(SysConstant.PRODUCT_THREE);
//        productTypes.add(SysConstant.PRODUCT_FOUR);
        if (productTypes.contains(product.getType()) || ((product.getType().equals(SysConstant.PRODUCT_FOUR)) && "1".equals(incomingInfo.getIsJydMortgage()))) {
            //生成抵押合同编号
            String dycontractNo = OrderNumUtil.getContractNo();//抵押合同编号
            map.put("MName", incomingInfo.getName());
            map.put("MContractId", dycontractNo);
            //车抵 异步调用
            if (product.getType().equals(SysConstant.PRODUCT_TWO)) {
                iAsyncService.carmortgage(incomingId, contractNo, dycontractNo, incomingInfo, incomingCommonLoans, loanAmount, Add, signContractDto.getOutId());
                //房抵 异步调用
            } else if (product.getType().equals(SysConstant.PRODUCT_THREE) || product.getType().equals(SysConstant.PRODUCT_FOUR)) {
                iAsyncService.roommortgage(incomingId, contractNo, dycontractNo, incomingInfo, incomingCommonLoans, loanAmount, Add, signContractDto.getOutId());
            }
            contractMap.put(SysConstant.CONTRACT_TYPE_THREE, dycontractNo);
        }
        String A4 = "";
        switch (signContractDto.getControversy()) {
            case SysConstant.CONTROVERSY_ONE:
                A4 = "3";
                break;
            case SysConstant.CONTROVERSY_TOW:
                A4 = "2";
                break;
            case SysConstant.CONTROVERSY_THREE:
                A4 = "1";
                break;
        }

        map.put("A4", A4);
        map.put("ArbitratAddress", signContractDto.getCityRemark());
        map.put("Add", Add);
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(idCard);
        c1.setSignType(3);
        c1.setNoticeMobile(userPhone);
        c1.setIsNotice(0);
        c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方1");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);


        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());

        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
//        saveContractInfo(contractCreate, oldContract, data, contractNo, incomingInfo, SysConstant.CONTRACT_TYPE_TOW);
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_TOW);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(signContractDto.getOutId());
//        c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);
        contractMap.put(SysConstant.CONTRACT_TYPE_TOW, contractNo);
        return contractMap;
    }

    //公证车抵押合同
    public String notarizationRoommortgage(Integer id, String dkcontractNo, String dycontractNo, IncomingInfo incomingInfo, List<IncomingCommonLoan> incomingCommonLoans, BigDecimal outLoan, String Add, Integer outId) {
        Date contractCreate = new Date();
        IncomingInfoSupp incomingInfoSupp = incomingInfoSuppMapper.selectById(id);
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        //生成合同
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(dycontractNo);//合同编号
        contractInput.setContractName("抵押合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getFdtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("ContractId", dycontractNo);
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1Address", incomingInfo.getAddress());
        map.put("Y1Phone", userPhone);
        map.put("Y1Email", incomingInfo.getEmail());
        //判断是否有共借人
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {
                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();
                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "CardId", card);
                map.put("Y" + i + "Address", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());


                map.put("Y" + i + "NameS", incomingCommonLoan.getHouseOwners());
                map.put("Y" + i + "CardId", incomingCommonLoan.getIdCard());
                map.put("Y" + i + "MortgageId", incomingCommonLoan.getHouseNo());
                map.put("Y" + i + "MortgageAdd", incomingCommonLoan.getHouseAddress());
                map.put("Y" + i + "MortgageSize", incomingCommonLoan.getHouseBuildingArea() != null ? String.valueOf(incomingCommonLoan.getHouseBuildingArea()) : "");
                if (incomingCommonLoan.getHouseValuation() != null) {
                    map.put("Y" + i + "MortgageValue", String.valueOf(incomingCommonLoan.getHouseValuation().multiply(BigDecimal.valueOf(10000))));
                }
                if (StringUtils.isNotBlank(incomingCommonLoan.getHouseUseType())) {
                    String name = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingCommonLoan.getHouseUseType()).eq(Dictionary::getType, "usageStatus")).getName();
                    map.put("Y" + i + "MortgageState", name);
                }
            }
        }
        map.put("LoanContractId", dkcontractNo);
        map.put("RMB", String.valueOf(outLoan));
        map.put("CapitalRMB", XkdUtil.number2CNMontrayUnit(outLoan));
        map.put("Y1Add", Add);

        map.put("Y1NameS", incomingInfoSupp.getHouseOwners());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1MortgageId", incomingInfoSupp.getHouseNo());
        map.put("Y1MortgageAdd", incomingInfoSupp.getHouseAddress());
        map.put("Y1MortgageSize", String.valueOf(incomingInfoSupp.getHouseBuildingArea()));
        map.put("Y1MortgageValue", String.valueOf(incomingInfoSupp.getHouseValuation().multiply(BigDecimal.valueOf(10000))));
        String name = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingInfoSupp.getHouseUseType()).eq(Dictionary::getType, "carType")).getName();
        map.put("Y1MortgageState", name);

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        //下载抵押合同
        String s = downloadContract(dycontractNo, incomingInfo.getCompanyId());
        //保存签约合同信息
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(dycontractNo);
        c.setType(SysConstant.CONTRACT_TYPE_THREE);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName("抵押合同");
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setContract(s);
        c.setPreviewUrl(previewUrl);
        c.setOutId(outId);
        contractMapper.insert(c);
        return localUrlPath + s;

    }

    //车抵押合同
    @Override
    public void roommortgage(Integer id, String dkcontractNo, String dycontractNo, IncomingInfo incomingInfo, List<IncomingCommonLoan> incomingCommonLoans, BigDecimal outLoan, String Add, Integer outId) {
        Date contractCreate = new Date();
        IncomingInfoSupp incomingInfoSupp = incomingInfoSuppMapper.selectById(id);
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        //生成合同
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(dycontractNo);//合同编号
        contractInput.setContractName("抵押合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getFdtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("ContractId", dycontractNo);
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1Address", incomingInfo.getAddress());
        map.put("Y1Phone", userPhone);
        map.put("Y1Email", incomingInfo.getEmail());
        //判断是否有共借人
        List<ContractUserInput> userInputList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {
                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();
                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "CardId", card);
                map.put("Y" + i + "Address", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());


                map.put("Y" + i + "NameS", incomingCommonLoan.getHouseOwners());
                map.put("Y" + i + "CardId", incomingCommonLoan.getIdCard());
                map.put("Y" + i + "MortgageId", incomingCommonLoan.getHouseNo());
                map.put("Y" + i + "MortgageAdd", incomingCommonLoan.getHouseAddress());
                map.put("Y" + i + "MortgageSize", incomingCommonLoan.getHouseBuildingArea() != null ? String.valueOf(incomingCommonLoan.getHouseBuildingArea()) : "");
                if (incomingCommonLoan.getHouseValuation() != null) {
                    map.put("Y" + i + "MortgageValue", String.valueOf(incomingCommonLoan.getHouseValuation().multiply(BigDecimal.valueOf(10000))));
                }
                if (StringUtils.isNotBlank(incomingCommonLoan.getHouseUseType())) {
                    String name = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingCommonLoan.getHouseUseType()).eq(Dictionary::getType, "usageStatus")).getName();
                    map.put("Y" + i + "MortgageState", name);
                }
                //添加共借人签署方
                ContractUserInput c = new ContractUserInput();
                c.setContractNo(dycontractNo);
                c.setAccount(card);
                c.setSignType(3);
                c.setNoticeMobile(decryptPhone);
                c.setIsNotice(0);
                c.setValidateType(6);//手写识别签名+短信签约（仅限个人）

                List<UserSignStrategyInput> s = new ArrayList<>(5);
                UserSignStrategyInput u = new UserSignStrategyInput();
                u.setAttachNo(1);
                u.setLocationMode(4);
                u.setSignKey("乙方" + i);
                s.add(u);
                c.setSignStrategyList(s);
                userInputList.add(c);
            }
        }
        map.put("LoanContractId", dkcontractNo);
        map.put("RMB", String.valueOf(outLoan));
        map.put("CapitalRMB", XkdUtil.number2CNMontrayUnit(outLoan));
        map.put("Y1Add", Add);

        map.put("Y1NameS", incomingInfoSupp.getHouseOwners());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1MortgageId", incomingInfoSupp.getHouseNo());
        map.put("Y1MortgageAdd", incomingInfoSupp.getHouseAddress());
        map.put("Y1MortgageSize", String.valueOf(incomingInfoSupp.getHouseBuildingArea()));
        map.put("Y1MortgageValue", String.valueOf(incomingInfoSupp.getHouseValuation().multiply(BigDecimal.valueOf(10000))));
        String name = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingInfoSupp.getHouseUseType()).eq(Dictionary::getType, "usageStatus")).getName();
        map.put("Y1MortgageState", name);

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(dycontractNo);
        c1.setAccount(incomingInfo.getIdCard());
        c1.setSignType(3);
        c1.setNoticeMobile(userPhone);
        c1.setIsNotice(0);
        c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方1");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(dycontractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起抵押合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        //查询是否签署过合同
//        Contract oldContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getIncomingId, id).eq(Contract::getType, SysConstant.CONTRACT_TYPE_THREE));
//        saveContractInfo(contractCreate, oldContract, data, dycontractNo, incomingInfo, SysConstant.CONTRACT_TYPE_THREE);
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(dycontractNo);
        c.setType(SysConstant.CONTRACT_TYPE_THREE);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(outId);
//        c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);

    }

    //公证车抵押合同
    public NotarizationCarmortgageVo notarizationCarmortgage(Integer id, String dkcontractNo, String dycontractNo, IncomingInfo incomingInfo, List<IncomingCommonLoan> incomingCommonLoans, BigDecimal outLoan, String Add, Integer outId) {
        Date contractCreate = new Date();
        ArrayList<MortgageInfo> mortgageInfos = new ArrayList<>();
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        //生成合同
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(dycontractNo);//合同编号
        contractInput.setContractName("抵押合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getGZcdtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("AgreementNo", dycontractNo);
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1ChineseID", incomingInfo.getIdCard());
        map.put("Y1Add", incomingInfo.getAddress());
        map.put("Y1Phone", userPhone);
        map.put("Y1Email", incomingInfo.getEmail());
        IncomingInfoSupp incomingInfoSupp = incomingInfoSuppMapper.selectById(id);

        //判断是否有共借人
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {
                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();
                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "ChineseID", card);
                map.put("Y" + i + "Add", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());

                String carType = "";
                String UsageType = "";
                if (StringUtils.isNotBlank(incomingCommonLoan.getCarType())) {
                    carType = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingCommonLoan.getCarType()).eq(Dictionary::getType, "carType")).getName();
                    map.put("VehicleType" + i, carType);
                }
                if (StringUtils.isNotBlank(incomingCommonLoan.getCarUseType())) {
                    UsageType = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingCommonLoan.getCarUseType()).eq(Dictionary::getType, "natureOfUse")).getName();
                    map.put("UsageType" + i, UsageType);
                }
                map.put("Number" + i, incomingCommonLoan.getCarNo());
                map.put("VIN" + i, incomingCommonLoan.getCarCode());
                map.put("EngineNumber" + i, incomingCommonLoan.getCarEngineNo());
                map.put("BrandandModel" + i, incomingCommonLoan.getCarBrand());
                if (incomingCommonLoan.getCarValuation() != null) {
                    map.put("AppraisedValue" + i, String.valueOf(incomingCommonLoan.getCarValuation().multiply(BigDecimal.valueOf(10000))));
                }
                map.put("SecuredDebtAmount" + i, incomingCommonLoan.getGuaAmount() != null ? String.valueOf(incomingCommonLoan.getGuaAmount()) : "");
                if (incomingCommonLoan.getCollateralSwitch().equals("1")) {
                    MortgageInfo mortgageInfo = new MortgageInfo();
                    mortgageInfo.setType(carType);
                    mortgageInfo.setPropertyOwner(incomingCommonLoan.getCarOwners());
                    mortgageInfo.setCardNum(incomingCommonLoan.getIdCard());
                    mortgageInfo.setUseNature(UsageType);
                    mortgageInfo.setLicensePlateNumber(incomingCommonLoan.getCarNo());
                    mortgageInfo.setIdentifyCode(incomingCommonLoan.getCarCode());
                    mortgageInfo.setEngineNum(incomingCommonLoan.getCarEngineNo());
                    mortgageInfo.setBrandModel(incomingCommonLoan.getCarBrand());
                    mortgageInfo.setAssessValue(incomingCommonLoan.getCarValuation());
                    mortgageInfo.setGuaranteedAmount(incomingCommonLoan.getGuaAmount());
                    mortgageInfos.add(mortgageInfo);
                }
            }
        }

        map.put("DKAgreementNo", dkcontractNo);
        map.put("RMB", String.valueOf(outLoan));
        map.put("CNY", XkdUtil.number2CNMontrayUnit(outLoan));
//        map.put("Add", Add);
        String carType = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingInfoSupp.getCarType()).eq(Dictionary::getType, "carType")).getName();
        map.put("VehicleType1", carType);
        String name = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingInfoSupp.getCarUseType()).eq(Dictionary::getType, "natureOfUse")).getName();
        map.put("UsageType", name);
        map.put("Number", incomingInfoSupp.getCarNo());
        map.put("VIN1", incomingInfoSupp.getCarCode());
        map.put("EngineNumber1", incomingInfoSupp.getCarEngineNo());
        map.put("BrandandModel1", incomingInfoSupp.getCarBrand());
        map.put("AppraisedValue1", String.valueOf(incomingInfoSupp.getCarValuation().multiply(BigDecimal.valueOf(10000))));
        map.put("SecuredDebtAmount1", String.valueOf(incomingInfoSupp.getGuaAmount()));

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        //下载抵押合同
        String s = downloadContract(dycontractNo, incomingInfo.getCompanyId());
        //保存签约合同信息
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(dycontractNo);
        c.setType(SysConstant.CONTRACT_TYPE_THREE);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName("抵押合同");
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(previewUrl);
        c.setContract(s);
        c.setOutId(outId);
        contractMapper.insert(c);
        //主借人车辆抵押信息
        MortgageInfo mortgageInfo = new MortgageInfo();
        mortgageInfo.setType(carType);
        mortgageInfo.setPropertyOwner(incomingInfoSupp.getCarOwners());
        mortgageInfo.setCardNum(incomingInfo.getIdCard());
        mortgageInfo.setUseNature(name);
        mortgageInfo.setLicensePlateNumber(incomingInfoSupp.getCarNo());
        mortgageInfo.setIdentifyCode(incomingInfoSupp.getCarCode());
        mortgageInfo.setEngineNum(incomingInfoSupp.getCarEngineNo());
        mortgageInfo.setBrandModel(incomingInfoSupp.getCarBrand());
        mortgageInfo.setAssessValue(incomingInfoSupp.getCarValuation());
        mortgageInfo.setGuaranteedAmount(incomingInfoSupp.getGuaAmount());
        mortgageInfos.add(mortgageInfo);
        return new NotarizationCarmortgageVo(localUrlPath + s, mortgageInfos);
    }

    //车抵押合同
    @Override
    public void carmortgage(Integer id, String dkcontractNo, String dycontractNo, IncomingInfo incomingInfo, List<IncomingCommonLoan> incomingCommonLoans, BigDecimal outLoan, String Add, Integer outId) {
        Date contractCreate = new Date();
        IncomingInfoSupp incomingInfoSupp = incomingInfoSuppMapper.selectById(id);
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        //生成合同
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(dycontractNo);//合同编号
        contractInput.setContractName("抵押合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getCdtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("AgreementNo", dycontractNo);
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1ChineseID", incomingInfo.getIdCard());
        map.put("Y1Add", incomingInfo.getAddress());
        map.put("Y1Phone", userPhone);
        map.put("Y1Email", incomingInfo.getEmail());

        //判断是否有共借人
        List<ContractUserInput> userInputList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {
                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();
                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "ChineseID", card);
                map.put("Y" + i + "Add", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());

                if (StringUtils.isNotBlank(incomingCommonLoan.getCarType())) {
                    String carType = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingCommonLoan.getCarType()).eq(Dictionary::getType, "carType")).getName();
                    map.put("VehicleType" + i, carType);
                }
                if (StringUtils.isNotBlank(incomingCommonLoan.getCarUseType())) {
                    String name = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingCommonLoan.getCarUseType()).eq(Dictionary::getType, "natureOfUse")).getName();
                    map.put("UsageType" + i, name);
                }
                map.put("Number" + i, incomingCommonLoan.getCarNo());
                map.put("VIN" + i, incomingCommonLoan.getCarCode());
                map.put("EngineNumber" + i, incomingCommonLoan.getCarEngineNo());
                map.put("BrandandModel" + i, incomingCommonLoan.getCarBrand());
                if (incomingCommonLoan.getCarValuation() != null) {
                    map.put("AppraisedValue" + i, String.valueOf(incomingCommonLoan.getCarValuation().multiply(BigDecimal.valueOf(10000))));
                }
                map.put("SecuredDebtAmount" + i, incomingCommonLoan.getGuaAmount() != null ? String.valueOf(incomingCommonLoan.getGuaAmount()) : "");

                //添加共借人签署方
                ContractUserInput c = new ContractUserInput();
                c.setContractNo(dycontractNo);
                c.setAccount(card);
                c.setSignType(3);
                c.setNoticeMobile(decryptPhone);
                c.setIsNotice(0);
                c.setValidateType(6);//手写识别签名+短信签约（仅限个人）

                List<UserSignStrategyInput> s = new ArrayList<>(5);
                UserSignStrategyInput u = new UserSignStrategyInput();
                u.setAttachNo(1);
                u.setLocationMode(4);
                u.setSignKey("乙方" + i);
                s.add(u);
                c.setSignStrategyList(s);
                userInputList.add(c);
            }
        }

        map.put("DKAgreementNo", dkcontractNo);
        map.put("RMB", String.valueOf(outLoan));
        map.put("CNY", XkdUtil.number2CNMontrayUnit(outLoan));
        map.put("Add", Add);
        String carType = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingInfoSupp.getCarType()).eq(Dictionary::getType, "carType")).getName();
        map.put("VehicleType1", carType);
        String name = dictionaryMapper.selectOne(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getCode, incomingInfoSupp.getCarUseType()).eq(Dictionary::getType, "natureOfUse")).getName();
        map.put("UsageType", name);
        map.put("Number", incomingInfoSupp.getCarNo());
        map.put("VIN1", incomingInfoSupp.getCarCode());
        map.put("EngineNumber1", incomingInfoSupp.getCarEngineNo());
        map.put("BrandandModel1", incomingInfoSupp.getCarBrand());
        map.put("AppraisedValue1", String.valueOf(incomingInfoSupp.getCarValuation().multiply(BigDecimal.valueOf(10000))));
        map.put("SecuredDebtAmount1", String.valueOf(incomingInfoSupp.getGuaAmount()));

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(dycontractNo);
        c1.setAccount(incomingInfo.getIdCard());
        c1.setSignType(3);
        c1.setNoticeMobile(userPhone);
        c1.setIsNotice(0);
        c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方1");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(dycontractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起抵押合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        //查询是否签署过合同
//        Contract oldContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getIncomingId, id).eq(Contract::getType, SysConstant.CONTRACT_TYPE_THREE));
//        saveContractInfo(contractCreate, oldContract, data, dycontractNo, incomingInfo, SysConstant.CONTRACT_TYPE_THREE);
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(dycontractNo);
        c.setType(SysConstant.CONTRACT_TYPE_THREE);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(outId);
//        c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);
    }

    //公证生成合同
    public String notarizationGuarantee(IncomingInfo incomingInfo, String DKContractNo, String dbContractNo, String Add, List<IncomingCommonLoan> incomingCommonLoans, SignContractDto signContractDto) {
        Date contractCreate = new Date();
        //查询进件信息
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        //生成合同
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(dbContractNo);//合同编号
        contractInput.setContractName("担保合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getGZdbtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("ContractId", dbContractNo);
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1Address", incomingInfo.getAddress());
        map.put("Y1Phone", userPhone);
        map.put("Y1Email", incomingInfo.getEmail());

        //判断是否有共借人
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {
                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();
                //添加陌生用户
                addStrangerV2(card);

                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "CardId", card);
                map.put("Y" + i + "Address", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());
            }
        }
        map.put("BName", incomingInfo.getGuarantorName());
        map.put("BCardId", incomingInfo.getGuarantorIdCard());
        map.put("BAddress", incomingInfo.getGuarantorAddress());
        map.put("BPhone", AESUtil.decrypt(incomingInfo.getGuarantorPhone(), aesKey));
        map.put("BEmail", incomingInfo.getGuarantorMail());
        map.put("DKContractId", DKContractNo);
        map.put("RMB", String.valueOf(signContractDto.getLoanAmount()));
        map.put("CapitalRMB", XkdUtil.number2CNMontrayUnit(signContractDto.getLoanAmount()));
        map.put("Purpose", signContractDto.getUsed());
        String A1 = "";
        switch (signContractDto.getControversy()) {
            case SysConstant.CONTROVERSY_ONE:
                A1 = "3";
                break;
            case SysConstant.CONTROVERSY_TOW:
                A1 = "2";
                break;
            case SysConstant.CONTROVERSY_THREE:
                A1 = "1";
                break;
        }
        map.put("A1", A1);
        map.put("ArbitratAddress", signContractDto.getCityRemark());
//        map.put("Add", Add);

        map.put("VehicleType1", Add);
        map.put("UsageType", Add);

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        //下载担保合同
        String s = downloadContract(dbContractNo, incomingInfo.getCompanyId());
        //保存签约合同信息
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(dbContractNo);
        c.setType(SysConstant.CONTRACT_TYPE_FIVE);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName("担保合同");
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(previewUrl);
        c.setContract(s);
        c.setOutId(signContractDto.getOutId());
        contractMapper.insert(c);
        return localUrlPath + s;
    }

    @Override
    public void guarantee(Credit credit, IncomingInfo incomingInfo, String DKContractNo, String dbContractNo, String Add, List<IncomingCommonLoan> incomingCommonLoans, SignContractDto signContractDto) {
        Date contractCreate = new Date();
        //查询进件信息
//        Credit credit = creditMapper.selectOne(new LambdaQueryWrapper<Credit>().eq(Credit::getIncomingId, id));
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        String idCard = incomingInfo.getIdCard();
        String guarantorIdCard = incomingInfo.getGuarantorIdCard();//担保人
        String guarantorPhone = AESUtil.decrypt(incomingInfo.getGuarantorPhone(), aesKey);

        //添加陌生用户
        addStrangerV2(idCard);
        addStrangerV2(guarantorIdCard);
        //生成合同
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(dbContractNo);//合同编号
        contractInput.setContractName("担保合同");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getDbtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("ContractId", dbContractNo);
        map.put("Y1Name", incomingInfo.getName());
        map.put("Y1CardId", incomingInfo.getIdCard());
        map.put("Y1Address", incomingInfo.getAddress());
        map.put("Y1Phone", userPhone);
        map.put("Y1Email", incomingInfo.getEmail());

        //判断是否有共借人
        List<ContractUserInput> userInputList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {
                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String decryptPhone = AESUtil.decrypt(incomingCommonLoan.getPhone(), aesKey);
                String card = incomingCommonLoan.getIdCard();
                //添加陌生用户
                addStrangerV2(card);

                map.put("Y" + i + "Name", incomingCommonLoan.getName());
                map.put("Y" + i + "CardId", card);
                map.put("Y" + i + "Address", incomingCommonLoan.getAddress());
                map.put("Y" + i + "Phone", decryptPhone);
                map.put("Y" + i + "Email", incomingCommonLoan.getMail());

                //添加共借人签署方
                ContractUserInput c = new ContractUserInput();
                c.setContractNo(dbContractNo);
                c.setAccount(card);
                c.setSignType(3);
                c.setNoticeMobile(decryptPhone);
                c.setIsNotice(0);
                c.setValidateType(6);//手写识别签名+短信签约（仅限个人）

                List<UserSignStrategyInput> s = new ArrayList<>(5);
                UserSignStrategyInput u = new UserSignStrategyInput();
                u.setAttachNo(1);
                u.setLocationMode(4);
                u.setSignKey("乙方" + i);
                s.add(u);
                c.setSignStrategyList(s);
                userInputList.add(c);
            }
        }
        //添加担保人
        addStrangerV2(incomingInfo.getGuarantorIdCard());
        map.put("BName", incomingInfo.getGuarantorName());
        map.put("BCardId", incomingInfo.getGuarantorIdCard());
        map.put("BAddress", incomingInfo.getGuarantorAddress());
        map.put("BPhone", AESUtil.decrypt(incomingInfo.getGuarantorPhone(), aesKey));
        map.put("BEmail", incomingInfo.getGuarantorMail());
        map.put("DKContractId", DKContractNo);
        map.put("RMB", String.valueOf(signContractDto.getLoanAmount()));
        map.put("CapitalRMB", XkdUtil.number2CNMontrayUnit(signContractDto.getLoanAmount()));
        map.put("Purpose", signContractDto.getUsed());
        String A1 = "";
        switch (signContractDto.getControversy()) {
            case SysConstant.CONTROVERSY_ONE:
                A1 = "3";
                break;
            case SysConstant.CONTROVERSY_TOW:
                A1 = "2";
                break;
            case SysConstant.CONTROVERSY_THREE:
                A1 = "1";
                break;
        }
        map.put("A1", A1);
        map.put("ArbitratAddress", signContractDto.getCityRemark());
        map.put("Add", Add);

        map.put("VehicleType1", Add);
        map.put("UsageType", Add);


        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(dbContractNo);
        c1.setAccount(idCard);
        c1.setSignType(3);
        c1.setNoticeMobile(userPhone);
        c1.setIsNotice(0);
        c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方1");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 担保人
         * */
        ContractUserInput c3 = new ContractUserInput();
        c3.setContractNo(dbContractNo);
        c3.setAccount(guarantorIdCard);
        c3.setSignType(3);
        c3.setNoticeMobile(guarantorPhone);
        c3.setIsNotice(0);
        c3.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s3 = new ArrayList<>(5);
        UserSignStrategyInput u3 = new UserSignStrategyInput();
        u3.setAttachNo(1);
        u3.setLocationMode(4);
        u3.setSignKey("丙方");
        s3.add(u3);
        c3.setSignStrategyList(s3);

        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(dbContractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);
        userInputList.add(c1);
        userInputList.add(c2);
        userInputList.add(c3);

        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        //查询是否签署过合同
//        Contract oldContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getIncomingId, id).eq(Contract::getType, SysConstant.CONTRACT_TYPE_FIVE));
//        saveContractInfo(contractCreate, oldContract, data, dbContractNo, incomingInfo, SysConstant.CONTRACT_TYPE_FIVE);

        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(dbContractNo);
        c.setType(SysConstant.CONTRACT_TYPE_FIVE);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(signContractDto.getOutId());
//        c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);
    }

    //公证委托划扣授权书
    public NotarizationContractVo notarizationWithhold(SignContractDto signContractDto, String dkContractNo) {
        Date contractCreate = new Date();
        String contractName = "委托划扣授权书";
        Integer incomingId = signContractDto.getIncomingId();
        //查询进件信息
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        Credit credit = creditMapper.selectOne(new LambdaQueryWrapper<Credit>().eq(Credit::getIncomingId, incomingId));

        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        String idCard = incomingInfo.getIdCard();
        //添加陌生用户
        addStrangerV2(idCard);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName(contractName);
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getGZdktemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("UserName", incomingInfo.getName());
        map.put("UserID", incomingInfo.getIdCard());
        map.put("JKAgreementNo", dkContractNo);
        map.put("OpeningBank", credit.getRepayBank());
        map.put("BankAcc", credit.getRepayAccount());
//        String Add = cityInfoMapper.selectAddress(incomingInfo.getProvince(), incomingInfo.getCity());
//        map.put("Add", Add);
        map.put("JKTel", userPhone);
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        String s = downloadContract(contractNo, incomingInfo.getCompanyId());

        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_SEVEN);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(contractName);
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(previewUrl);
        c.setContract(s);
        c.setOutId(signContractDto.getOutId());
        contractMapper.insert(c);

        NotarizationContractVo notarizationContractVo = new NotarizationContractVo();
        notarizationContractVo.setContractNo(contractNo);
        notarizationContractVo.setContractType(SysConstant.CONTRACT_TYPE_SEVEN);
        notarizationContractVo.setContractUrl(localUrlPath + s);
        notarizationContractVo.setContractName(s.substring(s.lastIndexOf("/") + 1));
        notarizationContractVo.setFileCode("1018");

        return notarizationContractVo;
    }

    @Override
    public String withhold(SignContractDto signContractDto, String dkContractNo) {
        Date contractCreate = new Date();
        Integer incomingId = signContractDto.getIncomingId();
        //查询进件信息
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        Credit credit = creditMapper.selectOne(new LambdaQueryWrapper<Credit>().eq(Credit::getIncomingId, incomingId));

        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        String idCard = incomingInfo.getIdCard();
        //添加陌生用户
        addStrangerV2(idCard);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("委托划扣授权书");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getDktemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("UserName", incomingInfo.getName());
        map.put("UserID", incomingInfo.getIdCard());
//        Contract JKContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getIncomingId, id).eq(Contract::getType, SysConstant.CONTRACT_TYPE_TOW));
        map.put("JKAgreementNo", dkContractNo);
        map.put("OpeningBank", credit.getRepayBank());
        map.put("BankAcc", credit.getRepayAccount());
        String Add = null;
        if (incomingInfo.getCity() == null) {
            Add = signContractDto.getCity();
        } else {
            Add = cityInfoMapper.selectAddress(incomingInfo.getProvince(), incomingInfo.getCity());
        }
        map.put("Add", Add);
        map.put("JKTel", userPhone);
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();

        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(idCard);
        c1.setSignType(3);
        c1.setNoticeMobile(userPhone);
        c1.setIsNotice(0);
        c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());

        ContractOutput data = contractOutputApiRespBody.getData();
//        saveContractInfo(contractCreate, oldContract, data, contractNo, incomingInfo, SysConstant.CONTRACT_TYPE_SEVEN);
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_SEVEN);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(signContractDto.getOutId());
//        c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);
        return contractNo;
    }

    @Override
    @Transactional
    public void assignmentOfDebt(Integer companyId) {
        Date contractCreate = new Date();
        //判断企业是否认证
        Company company = companyMapper.selectById(companyId);
        if (!company.getAuthStatus().equals("1"))
            throw new XkdException("企业未认证");
        CompanyContract oldContract = checkCompanyContractInfo(companyId, SysConstant.COMPANY_CONTRACT_TYPE_ONE);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("债权转让协议");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getZqzrkjtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("contractNo", contractNo);
        map.put("ContractAdd", contractNo);
        map.put("YCoName", company.getCompanyName());
        map.put("YAddress", company.getLocationOfEnterprise());
        map.put("Contact", company.getContacts());
        map.put("YPhone", AESUtil.decrypt(company.getCompanyPhone(), aesKey));
//        map.put("BankID", loans_in_account_offline);
        Date date = new Date();
        String startTime = DateUtil.format(date, "yyyy-MM-dd");
        String endTime = DateUtil.format(DateUtil.offsetMonth(date, 12), "yyyy-MM-dd");
        map.put("StartTime", startTime);
        map.put("EndTime", endTime);
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getCompanyNotifyUrl(), aqHtProperties.getCompanyContractCallback());
        //添加签署方发起合同
        /*
         * 资方
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();

        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(company.getUnifiedSocialCreditCode());
        c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("债转转让框架协议添加签署方发起合同" + contractOutputApiRespBody.getMsg());

        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        saveCompanyContractInfo(contractCreate, oldContract, data, contractNo, companyId, SysConstant.COMPANY_CONTRACT_TYPE_ONE);
    }

    @Override
    public void extraBorrowing(Integer id, String Y2bank, String Y2BankCard, Integer outId, Credit credit) {
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(id);
        Contract contract1 = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getOutId, outId).eq(Contract::getType, SysConstant.CONTRACT_TYPE_TOW));
        String phone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        Date startTime = contract1.getStartTime();
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("补充协议");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getJkbctemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("ContractId", contractNo);
        map.put("YName", incomingInfo.getName());
        map.put("YCardId", incomingInfo.getIdCard());
        map.put("YAddress", incomingInfo.getAddress());
        map.put("YPhone", phone);
        map.put("Y1", String.valueOf(DateUtil.year(startTime)));
        map.put("M1", String.valueOf(DateUtil.month(startTime) + 1));
        map.put("D1", String.valueOf(DateUtil.dayOfMonth(startTime)));
        map.put("JKContractId", contract1.getContractNo());
        map.put("Ybank", credit.getBank());
        map.put("YBankCard", credit.getReceivingAccount());
        map.put("Y2bank", Y2bank);
        map.put("Y2BankCard", Y2BankCard);
        Date date = new Date();
        map.put("Y2", String.valueOf(DateUtil.year(date)));
        map.put("M2", String.valueOf(DateUtil.month(date) + 1));
        map.put("D2", String.valueOf(DateUtil.dayOfMonth(date)));

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();

        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(incomingInfo.getIdCard());
        c1.setSignType(2);
//        c1.setNoticeMobile(phone);
//        c1.setIsNotice(1);
//        c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());

        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        Contract c = new Contract();
        c.setIncomingId(id);
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_FOUR);
        c.setStatus("1");
        c.setStartTime(new Date());
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(outId);
        c.setContractTime(new Date());
        contractMapper.insert(c);

    }

    //公证还款承诺函
    public NotarizationContractVo notarizationRepaymentCommitmentLetter(SignContractDto signContractDto, String dkContractNo) {
        Date contractCreate = new Date();
        String contractName = "还款承诺函";
        Integer incomingId = signContractDto.getIncomingId();
        BigDecimal loanAmount = signContractDto.getLoanAmount();
        //查询进件信息
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName(contractName);
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getGZhkclhtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("Name", incomingInfo.getName());
        map.put("ChineseID", incomingInfo.getIdCard());
        map.put("ContractNo", dkContractNo);
        map.put("RMB", String.valueOf(loanAmount));
        map.put("CNY", XkdUtil.number2CNMontrayUnit(loanAmount));
        map.put("Utilization", signContractDto.getUsed());

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        String previewUrl = createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());
        //下载合同
        String s = downloadContract(contractNo, incomingInfo.getCompanyId());

        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_SIX);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(contractName);
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(previewUrl);
        c.setContract(s);
        c.setOutId(signContractDto.getOutId());
        contractMapper.insert(c);

        NotarizationContractVo notarizationContractVo = new NotarizationContractVo();
        notarizationContractVo.setContractNo(contractNo);
        notarizationContractVo.setContractType(SysConstant.CONTRACT_TYPE_SIX);
        notarizationContractVo.setContractUrl(localUrlPath + s);
        notarizationContractVo.setContractName(s.substring(s.lastIndexOf("/") + 1));
        notarizationContractVo.setFileCode("1019");
        return notarizationContractVo;
    }

    /*
     * 还款承诺函
     * */
    @Override
    public String repaymentCommitmentLetter(SignContractDto signContractDto, String dkContractNo) {
        Date contractCreate = new Date();
        Integer incomingId = signContractDto.getIncomingId();
        BigDecimal loanAmount = signContractDto.getLoanAmount();
        //查询进件信息
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        String userPhone = AESUtil.decrypt(incomingInfo.getPhone(), aesKey);
        String idCard = incomingInfo.getIdCard();
        //添加陌生用户
        addStrangerV2(idCard);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("还款承诺函");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getHkclhtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("Name", incomingInfo.getName());
        map.put("ChineseID", incomingInfo.getIdCard());
        map.put("ContractNo", dkContractNo);
        map.put("RMB", String.valueOf(loanAmount));
        map.put("CNY", XkdUtil.number2CNMontrayUnit(loanAmount));
        map.put("Utilization", signContractDto.getUsed());

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 借款用户本人
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();

        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(incomingInfo.getIdCard());
        c1.setSignType(3);
        c1.setNoticeMobile(userPhone);
        c1.setIsNotice(0);
        c1.setValidateType(6);//手写识别签名+短信签约（仅限个人）

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("甲方");
        s1.add(u1);
        c1.setSignStrategyList(s1);

        userInputList.add(c1);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
//        saveContractInfo(contractCreate, oldContract, data, contractNo, incomingInfo, SysConstant.CONTRACT_TYPE_SIX);
        Contract c = new Contract();
        //第一次签约
        //保存签约合同信息
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_SIX);
        c.setStatus(SysConstant.CONTRACT_TODO);
        c.setStartTime(contractCreate);
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(signContractDto.getOutId());
//        c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);
        return contractNo;
    }

    @Override
    public void assignmentOfDebtConfirmation(Integer debtId, Integer companyId) {
        Date contractCreate = new Date();
        log.info("发送债权转让确认单");
        if (debtId == null)
            throw new XkdException("选择不能为空");
        Debt debt = debtMapper.selectById(debtId);
        Company company = companyMapper.selectById(companyId);
        //判断企业是否认证
        if (!company.getAuthStatus().equals("1"))
            throw new XkdException("企业未认证");
        Integer incomingId = debt.getIncomingId();
        Integer outId = debt.getOutId();
        Contract oldContract = checkContractInfo(debt.getOutId(), SysConstant.CONTRACT_TYPE_ELEVEN);
        CompanyContract companyContract = companyContractMapper.selectOne(new LambdaQueryWrapper<CompanyContract>().eq(CompanyContract::getType, SysConstant.COMPANY_CONTRACT_TYPE_ONE)
                .eq(CompanyContract::getCompanyId, companyId));
        if (companyContract == null || !companyContract.getStatus().equals(SysConstant.CONTRACT_DO))
            throw new XkdException("请先签署债权转让协议");
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        Product product = productMapper.selectById(incomingInfo.getProductId());
        String contractType = "";
        if (product.getType().equals(SysConstant.PRODUCT_FIVE)) {
            contractType = SysConstant.CONTRACT_TYPE_TWELVE;
        } else {
            contractType = SysConstant.CONTRACT_TYPE_TOW;
        }
        Contract JKContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getOutId, outId).eq(Contract::getType, contractType));

        OutInfo outInfo = outInfoMapper.selectOne(new LambdaQueryWrapper<OutInfo>().eq(OutInfo::getOutId, outId));

        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("债权转让确认单");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getZqzrtemplateNo());
        Map<String, String> map = new HashMap<>();

        map.put("Number", contractNo);
        map.put("AgreementNo", JKContract.getContractNo());
        map.put("AgreementDate", DateUtil.format(new Date(), "yyyy-MM-dd"));
        map.put("CoName", company.getCompanyName());
        map.put("Name1", incomingInfo.getName());
        map.put("身份证号1", incomingInfo.getIdCard());
        //判断是否有共借人
        List<IncomingCommonLoan> incomingCommonLoans = incomingCommonLoanMapper.selectList(new LambdaQueryWrapper<IncomingCommonLoan>().eq(IncomingCommonLoan::getIncomingId, incomingId));
        if (CollectionUtils.isNotEmpty(incomingCommonLoans)) {
            for (int i = 2; i <= incomingCommonLoans.size() + 1; i++) {
                IncomingCommonLoan incomingCommonLoan = incomingCommonLoans.get(i - 2);
                String card = incomingCommonLoan.getIdCard();
                //添加陌生用户
                addStrangerV2(card);
                map.put("Name" + i, incomingCommonLoan.getName());
                map.put("身份证号" + i, card);
            }
        }
        map.put("RMB", String.valueOf(debt.getRemainingShouldRepayPrincipal()));
        map.put("CNY", XkdUtil.number2CNMontrayUnit(debt.getRemainingShouldRepayPrincipal()));
        map.put("ZRMB", String.valueOf(debt.getPurchaseAmountOfBonds()));
        map.put("ZCNY", XkdUtil.number2CNMontrayUnit(debt.getPurchaseAmountOfBonds()));
        map.put("APR", outInfo.getRate() + "%");
        map.put("EndTime", DateUtil.format(outInfo.getOutEndTime(), "yyyy-MM-dd"));
        String loanMethod = outInfo.getLoanMethod();
//0--等额本金1--等额本息,2--等本等息,3--到期还本付息,4--先息后本
        if (loanMethod.equals("0")) {
            loanMethod = "等额本金";
        } else if (loanMethod.equals("1")) {
            loanMethod = "等额本息";
        } else if (loanMethod.equals("2")) {
            loanMethod = "等本等息";
        } else if (loanMethod.equals("3")) {
            loanMethod = "到期还本付息";
        } else if (loanMethod.equals("4")) {
            loanMethod = "先息后本";
        }
        map.put("paymentplan", loanMethod);
        map.put("ZZAgreementNo", companyContract.getContractOrder());

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        /*
         * 资方
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();
        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(company.getUnifiedSocialCreditCode());
        c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        log.info("债权通知发起合同结果：{}", contractOutputApiRespBody);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("债转确认单添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        log.info("保存债权合同通知" + contractOutputApiRespBody.getData());
        saveContractInfo(contractCreate, oldContract, data, contractNo, incomingInfo, SysConstant.CONTRACT_TYPE_ELEVEN, outInfo.getOutId());
    }


    @Override
    public void zjhfxsm(Integer companyId) {
        Date contractCreate = new Date();
        //判断企业是否认证
        Company company = companyMapper.selectById(companyId);
        if (!company.getAuthStatus().equals("1"))
            throw new XkdException("企业未认证");
        CompanyContract oldContract = checkCompanyContractInfo(companyId, SysConstant.COMPANY_CONTRACT_TYPE_TOW);

        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("资金合法合规声明");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getZjhfhgsmtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("CoName", company.getCompanyName());
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getCompanyNotifyUrl(), aqHtProperties.getCompanyContractCallback());

        //添加签署方发起合同
        /*
         * 资方
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();

        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(company.getUnifiedSocialCreditCode());
        c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("甲方");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        userInputList.add(c1);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("资金合法合规声明添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();

        //保存签约合同信息
        saveCompanyContractInfo(contractCreate, oldContract, data, contractNo, companyId, SysConstant.COMPANY_CONTRACT_TYPE_TOW);
    }

    @Override
    public void dkjqzm(Integer outId) {
        Date contractCreate = new Date();
        Contract oldContract = checkContractInfo(outId, SysConstant.CONTRACT_TYPE_TEN);
        //查询进件信息
        Debt debt = debtMapper.selectOne(new LambdaQueryWrapper<Debt>().eq(Debt::getOutId, outId));
        OutInfo outInfo = outInfoMapper.selectOne(new LambdaQueryWrapper<OutInfo>().eq(OutInfo::getOutId, outId));
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(outInfo.getIncomingId());
        Product product = productMapper.selectById(incomingInfo.getProductId());
        String contractType = "";
        if (product.getType().equals(SysConstant.PRODUCT_FIVE)) {
            contractType = SysConstant.CONTRACT_TYPE_TWELVE;
        } else {
            contractType = SysConstant.CONTRACT_TYPE_TOW;
        }
        Contract contract1 = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getOutId, outId).eq(Contract::getType, contractType));


        String idCard = incomingInfo.getIdCard();
        //添加陌生用户
        addStrangerV2(idCard);
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("贷款结清证明");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约
        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getDkjqzmtemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("Name", incomingInfo.getName());
        map.put("ChinseId", incomingInfo.getIdCard());
        map.put("StartTime", DateUtil.format(outInfo.getOutStartTime(), "yyyy-MM-dd"));//发起时间
        map.put("ContractNo", contract1.getContractNo());
        map.put("RMB", String.valueOf(debt.getOutAmount()));
        String s = XkdUtil.number2CNMontrayUnit(debt.getOutAmount());
        map.put("CNY", s);
        String EndTime = DateUtil.format(outInfo.getOutEndTime(), "yyyy-MM-dd");
        map.put("EndTime", EndTime);
        map.put("RepaymentDate", DateUtil.format(DateUtil.date(), "yyyy-MM-dd"));
        Date date = new Date();
        map.put("YY", String.valueOf(DateUtil.year(date)));
        map.put("MM", String.valueOf(DateUtil.month(date) + 1));
        map.put("DD", String.valueOf(DateUtil.dayOfMonth(date)));
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        //添加签署方发起合同
        List<ContractUserInput> userInputList = new ArrayList<>();
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);

        userInputList.add(c2);
        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("贷款结清证明添加签署方发起合同" + contractOutputApiRespBody.getMsg());
        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        saveContractInfo(contractCreate, oldContract, data, contractNo, incomingInfo, SysConstant.CONTRACT_TYPE_TEN, outId);
    }

    //委托代收付协议
    @Override
    public void wtdsf(Integer companyId) {
        Date contractCreate = new Date();
        CompanyContract companyContract = companyContractMapper.selectOne(new LambdaQueryWrapper<CompanyContract>().eq(CompanyContract::getCompanyId, companyId).eq(CompanyContract::getType, SysConstant.COMPANY_CONTRACT_TYPE_ONE));
        if (companyContract == null || !companyContract.getStatus().equals(SysConstant.CONTRACT_DO))
            throw new XkdException("请先签署债权转让协议");
        CompanyContract oldContract = checkCompanyContractInfo(companyId, SysConstant.COMPANY_CONTRACT_TYPE_THREE);
        Company company = companyMapper.selectById(companyId);
        //判断企业是否认证
        if (!company.getAuthStatus().equals("1"))
            throw new XkdException("企业未认证");
        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("委托代收付协议");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约

        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getWtdsftemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("AgreementNo", contractNo);
        map.put("DATE", DateUtil.format(new Date(), "yyyy-MM-dd"));
        map.put("CompanyName", company.getCompanyName());
        map.put("LE", company.getLegalEntityName());
        map.put("Addr", company.getLocationOfEnterprise());
        map.put("Contact", company.getContacts());
        map.put("Tel", AESUtil.decrypt(company.getLegalEntityPhone(), aesKey));
        map.put("ZZAgreementNo", companyContract.getContractOrder());
        map.put("AcctNo", company.getBankAccount());
        map.put("BankName", company.getOpeningBank());


        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getCompanyNotifyUrl(), aqHtProperties.getCompanyContractCallback());

        //添加签署方发起合同
        /*
         * 资方
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();

        ContractUserInput c1 = new ContractUserInput();
        c1.setContractNo(contractNo);
        c1.setAccount(company.getUnifiedSocialCreditCode());
        c1.setSignType(2);//无感签约
//        c1.setSealNo(company.getSealNo());//不传使用默认印章

        List<UserSignStrategyInput> s1 = new ArrayList<>(5);
        UserSignStrategyInput u1 = new UserSignStrategyInput();
        u1.setAttachNo(1);
        u1.setLocationMode(4);
        u1.setSignKey("乙方");
        s1.add(u1);
        c1.setSignStrategyList(s1);
        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);
        //骑缝章
        ArrayList<UserSignStrikeInput> userSignStrikeInputs = new ArrayList<>();
        UserSignStrikeInput userSignStrikeInput2 = new UserSignStrikeInput();
        userSignStrikeInput2.setAttachNo(1);
        userSignStrikeInput2.setCrossStyle(6);
        userSignStrikeInput2.setSignPage("1-0");
        userSignStrikeInputs.add(userSignStrikeInput2);
        c2.setSignStrikeList(userSignStrikeInputs);

        userInputList.add(c1);
        userInputList.add(c2);

        //发起合同签署
        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("委托代收付协议添加签署方发起合同" + contractOutputApiRespBody.getMsg());

        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        saveCompanyContractInfo(contractCreate, oldContract, data, contractNo, companyId, SysConstant.COMPANY_CONTRACT_TYPE_THREE);
    }

    @Override
    public void zqzrtz(Integer debtId, Integer companyId) {
        if (debtId == null)
            throw new XkdException("选择不能为空");
        Debt debt = debtMapper.selectById(debtId);
        Company company = companyMapper.selectById(companyId);
        Integer incomingId = debt.getIncomingId();
        Integer outId = debt.getOutId();
        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        Product product = productMapper.selectById(incomingInfo.getProductId());
        String contractType = "";
        if (product.getType().equals(SysConstant.PRODUCT_FIVE)) {
            contractType = SysConstant.CONTRACT_TYPE_TWELVE;
        } else {
            contractType = SysConstant.CONTRACT_TYPE_TOW;
        }
        Contract JKContract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>().eq(Contract::getOutId, outId).eq(Contract::getType, contractType));

        //生成合同
        String contractNo = OrderNumUtil.getContractNo();
        ContractInput contractInput = new ContractInput();
        contractInput.setContractNo(contractNo);//合同编号
        contractInput.setContractName("债权转让通知书");
        contractInput.setValidityTime(10);//合同签署剩余天数（系统当前时间+该天数=在此日期之前可以签署合同日期）
        contractInput.setSignOrder(1); // 签约方式，1：无序签约 2：顺序签约

        // 生成合同模板
        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(aqHtProperties.getZqzrtzstemplateNo());
        Map<String, String> map = new HashMap<>();
        map.put("Name", incomingInfo.getName());
        map.put("ContractTime", DateUtil.format(JKContract.getContractTime(), "yyyy-MM-dd"));
        map.put("JKContractNo", JKContract.getContractNo());
        map.put("Contract", company.getCompanyName());
        map.put("CNY", XkdUtil.number2CNMontrayUnit(debt.getOutAmount()));
        map.put("RMB", String.valueOf(debt.getOutAmount()));

        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);
        createContract(contractInput, aqHtProperties.getNotifyUrl(), aqHtProperties.getContractCallbackUrl());

        /*
         * 广东宝坤网络小额贷款有限公司
         * */
        List<ContractUserInput> userInputList = new ArrayList<>();
        ContractUserInput c2 = new ContractUserInput();
        c2.setContractNo(contractNo);
        c2.setAccount(aqHtProperties.getXdAccount());
        c2.setSignType(2);//无感签约
//        c2.setSealNo(aqHtProperties.getXdSealNo());

        List<UserSignStrategyInput> s2 = new ArrayList<>(5);
        UserSignStrategyInput u2 = new UserSignStrategyInput();
        u2.setAttachNo(1);
        u2.setLocationMode(4);
        u2.setSignKey("甲方");
        s2.add(u2);
        c2.setSignStrategyList(s2);

        userInputList.add(c2);

        ApiRespBody<ContractOutput> contractOutputApiRespBody = netSignClient.addSigner(userInputList);
        if (contractOutputApiRespBody.getCode() != 100000)
            throw new XkdException("添加签署人发起合同" + contractOutputApiRespBody.getMsg());

        ContractOutput data = contractOutputApiRespBody.getData();
        //保存签约合同信息
        Contract c = new Contract();
        c.setIncomingId(incomingInfo.getIncomingId());
        c.setContractNo(contractNo);
        c.setType(SysConstant.CONTRACT_TYPE_NINE);
        c.setStatus("1");
        c.setStartTime(new Date());
        c.setContractName(data.getContractName());
        c.setCompanyId(incomingInfo.getCompanyId());
        c.setPreviewUrl(data.getPreviewUrl());
        c.setOutId(outId);
//        c.setSignUrl(data.getSignUser().get(0).getSignUrl());
        contractMapper.insert(c);
    }


    public String createContract(ContractInput contractInput, String notifyUrl, String callbackUrl) throws XkdException {
        if (!active.equals("dev")) {//测试环境不要回调
            //回调地址  合同签署完成回调
            contractInput.setNotifyUrl(notifyUrl);
            contractInput.setCallbackUrl(callbackUrl);
        }
        ApiRespBody<ContractOutput> contract = netSignClient.createContract(contractInput);
        int code = contract.getCode();
        if (code != 100000)
            throw new XkdException("创建合同:" + contract.getMsg());
        return contract.getData().getPreviewUrl();
    }

    //添加陌生用户
    private void addStrangerV2(String idCard) {
        /*
         * 查询用户是否认证过
         * */
        ApiRespBody<SignUserOutput> user = netSignClient.getUser(idCard);
        if (user.getCode() == 100025) {
            log.info("用户不存在");
            /*
             * 添加陌生用户(个人)
             * */
            AddStrangerInput addStrangerInput = new AddStrangerInput();
            addStrangerInput.setAccount(idCard);
            addStrangerInput.setIdCard(idCard);
            addStrangerInput.setUserType(2);
            ApiRespBody<Void> voidApiRespBody = netSignClient.addStrangerV2(addStrangerInput);
            if (voidApiRespBody.getCode() != 100000)
                throw new XkdException("添加陌生用户失败");
        } else if (user.getCode() == 100000) {
            log.info("用户已认证成功");
            if (user.getData().getStatus().equals(1)) {
                log.info("用户有效");
            } else if (user.getData().getStatus().equals(0)) {
                throw new XkdException("用户未激活");
            } else if (user.getData().getStatus().equals(2)) {
                throw new XkdException("用户已锁定");
            }
        }
    }

    private String verify(VerifyCaptchaDto verifyCaptchaDto) {
        //认证验证码 流水号
        ApiRespBody<AuthOutput> authOutputApiRespBody = netSignClient.verifyCaptcha(verifyCaptchaDto.getSerialNo(), verifyCaptchaDto.getCaptcha());
        int code = authOutputApiRespBody.getCode();
        if (code == 100000) {
            return authOutputApiRespBody.getData().getSerialNo();
        } else {
            throw new XkdException(authOutputApiRespBody.getMsg());
        }
    }

    //accountNo : 唯一标识
    private String addEnterpriseUser(VerifyCaptchaDto verifyCaptchaDto) {
        //用例1：新增企业用户 实名认证流水号（serialNo）
        UserInput addUserRequest = new UserInput();
        addUserRequest.setAccount(verifyCaptchaDto.getCreditCode());
        addUserRequest.setSerialNo(verifyCaptchaDto.getSerialNo());
        addUserRequest.setMobile(verifyCaptchaDto.getMobile());
        addUserRequest.setSignPwd(signPwd + verifyCaptchaDto.getCreditCode());
        addUserRequest.setIsNotice(1);
        ApiRespBody<UserSeal> userSealApiRespBody = netSignClient.addEnterpriseUserV2(addUserRequest);
        int code = userSealApiRespBody.getCode();
        if (code == 100000) {
            return userSealApiRespBody.getData().getSealNo();
        } else {
            throw new XkdException(userSealApiRespBody.getMsg());
        }

    }

    private String authMobile3(CompanyAuthMobile3Dto companyAuthMobile3Dto) {
        AuthInput authInput = new AuthInput();
        authInput.setCompanyName(companyAuthMobile3Dto.getCompanyName());
        authInput.setCreditCode(companyAuthMobile3Dto.getCreditCode());
        authInput.setRealName(companyAuthMobile3Dto.getRealName());
        authInput.setIdCardNo(companyAuthMobile3Dto.getIdCardNo());
        authInput.setMobile(companyAuthMobile3Dto.getMobile());

        ApiRespBody<AuthOutput> authOutputApiRespBody = netSignClient.companyAuthMobile3(authInput);
        int code = authOutputApiRespBody.getCode();
        if (code == 100000) {
            return authOutputApiRespBody.getData().getSerialNo();
        } else {
            throw new XkdException(authOutputApiRespBody.getMsg());
        }
    }

    @Override
    public void addAllSigner(List<AddSignerVo> addSignerVos, Integer incomingId, Integer outId) {

        IncomingInfo incomingInfo = incomingInfoMapper.selectById(incomingId);
        for (AddSignerVo addSignerVo : addSignerVos) {
//            if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_TWELVE)) {
//                iAsyncService.addSignerBDJKHT(incomingInfo.getIncomingId(), addSignerVo.getContractNo(), incomingInfo,outId);
//            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_THIRTEEN)) {
//                iAsyncService.addSignerFLWSSDDZHT(incomingInfo.getIncomingId(), addSignerVo.getContractNo(), incomingInfo,outId);
//            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_FOURTEEN)) {
//                iAsyncService.addSignerWTDKSQSHT(incomingInfo, addSignerVo.getContractNo(),outId);
//            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_FIFTEEN)) {
//                InsuranceCompanyInfo insuranceCompanyInfo = insuranceCompanyInfoMapper.selectById(incomingInfo.getInsuranceCompanyId());
//                iAsyncService.addSignerWTTBHT(incomingInfo, addSignerVo.getContractNo(), insuranceCompanyInfo,outId);
//            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_SIXTEEN)) {
//                iAsyncService.addsignerTBSQS(incomingInfo, addSignerVo.getContractNo(),outId);
//            }
            if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_TWELVE)) {
                taskExecutor.execute(() -> {
                    addSignerBDJKHT(incomingInfo.getIncomingId(), addSignerVo.getContractNo(), incomingInfo, outId);
                });
            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_THIRTEEN)) {
                taskExecutor.execute(() -> {
                    addSignerFLWSSDDZHT(incomingInfo.getIncomingId(), addSignerVo.getContractNo(), incomingInfo, outId);
                });
            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_FOURTEEN)) {
                taskExecutor.execute(() -> {
                    addSignerWTDKSQSHT(incomingInfo, addSignerVo.getContractNo(), outId);
                });
            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_FIFTEEN)) {
                taskExecutor.execute(() -> {
                    InsuranceCompanyInfo insuranceCompanyInfo = insuranceCompanyInfoMapper.selectById(incomingInfo.getInsuranceCompanyId());
                    addSignerWTTBHT(incomingInfo, addSignerVo.getContractNo(), insuranceCompanyInfo, outId);
                });
            } else if (addSignerVo.getContractType().equals(SysConstant.CONTRACT_TYPE_SIXTEEN)) {
                taskExecutor.execute(() -> {
                    addsignerTBSQS(incomingInfo, addSignerVo.getContractNo(), outId);
                });
            }
        }
    }

    @Override
    public boolean getCapitalCompanyIsAuth(String creditCode, Integer companyId) {
        ApiRespBody<SignUserOutput> compUser = netSignClient.getCompUser(creditCode, null, null);
        if (compUser.getCode() != 100000)
            throw new XkdException("查询失败：" + compUser.getMsg());
        List<JSONObject> data = (List<JSONObject>) compUser.getData();
        if (CollectionUtils.isEmpty(data))
            return false;
        JSONObject jsonObject = data.get(0);
        Integer status = jsonObject.getInteger("status");
        if (status == 1) {//已认证
            Company company = new Company();
            company.setId(companyId);
            company.setAuthStatus(SysConstant.ZH_CHECK_PASS_STATUS);
            companyMapper.updateById(company);
        }
        return status.equals(1);
    }


}
